openapi: '3.0.3' info: title: Todo REST API version: '1.0.0' description: A RESTful API for managing todo items servers: - url: /api/v1 description: Base API path components: schemas: Todo: type: object properties: id: type: string format: uuid readOnly: true title: type: string minLength: 1 maxLength: 200 description: type: string maxLength: 2000 completed: type: boolean default: false dueDate: type: string format: date-time userId: type: string createdAt: type: string format: date-time readOnly: true updatedAt: type: string format: date-time readOnly: true required: - id - title - completed - userId - createdAt - updatedAt TodoCreate: type: object properties: title: type: string minLength: 1 maxLength: 200 description: type: string maxLength: 2000 dueDate: type: string format: date-time userId: type: string required: - title - userId TodoUpdate: type: object properties: title: type: string minLength: 1 maxLength: 200 description: type: string maxLength: 2000 completed: type: boolean dueDate: type: string format: date-time minProperties: 1 TodoList: type: object properties: data: type: string # items: # $ref: '#/components/schemas/Todo' metadata: type: string # properties: # total: # type: integer # minimum: 0 # limit: # type: integer # minimum: 1 # offset: # type: integer # minimum: 0 # required: # - total # - limit # - offset required: - data - metadata TodoResponse: type: object properties: data: type: string # $ref: '#/components/schemas/Todo' required: - data Error: type: object properties: error: type: string # properties: # code: # type: string # enum: # - VALIDATION_ERROR # - UNAUTHORIZED # - FORBIDDEN # - NOT_FOUND # - RATE_LIMIT_EXCEEDED # - INTERNAL_ERROR # message: # type: string # details: # type: array # items: # type: object # properties: # field: # type: string # message: # type: string # required: # - field # - message # required: # - code # - message parameters: TodoId: name: todoId in: path required: true schema: type: string format: uuid UserId: name: userId in: query required: true schema: type: string Status: name: status in: query schema: type: string enum: [active, completed] Limit: name: limit in: query schema: type: integer minimum: 1 maximum: 100 default: 50 Offset: name: offset in: query schema: type: integer minimum: 0 default: 0 SortBy: name: sortBy in: query schema: type: string enum: [createdAt, dueDate] default: createdAt SortOrder: name: sortOrder in: query schema: type: string enum: [asc, desc] default: desc securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT security: - bearerAuth: [] paths: /todos: get: summary: List todos parameters: - $ref: '#/components/parameters/UserId' - $ref: '#/components/parameters/Status' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Offset' - $ref: '#/components/parameters/SortBy' - $ref: '#/components/parameters/SortOrder' responses: '200': description: Successfully retrieved todos headers: ETag: schema: type: string Last-Modified: schema: type: string X-Request-ID: schema: type: string X-RateLimit-Limit: schema: type: integer X-RateLimit-Remaining: schema: type: integer X-RateLimit-Reset: schema: type: integer content: application/json: schema: $ref: '#/components/schemas/TodoList' '400': description: Invalid parameters content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '429': description: Too many requests headers: Retry-After: schema: type: integer content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' post: summary: Create a new todo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TodoCreate' responses: '201': description: Todo created successfully headers: Location: schema: type: string format: uri ETag: schema: type: string X-Request-ID: schema: type: string content: application/json: schema: $ref: '#/components/schemas/TodoResponse' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /todos/{todoId}: parameters: - $ref: '#/components/parameters/TodoId' get: summary: Get a specific todo responses: '200': description: Successfully retrieved todo headers: ETag: schema: type: string Last-Modified: schema: type: string X-Request-ID: schema: type: string content: application/json: schema: $ref: '#/components/schemas/TodoResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Todo not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' patch: summary: Update a todo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TodoUpdate' responses: '200': description: Todo updated successfully headers: ETag: schema: type: string X-Request-ID: schema: type: string content: application/json: schema: $ref: '#/components/schemas/TodoResponse' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Todo not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' delete: summary: Delete a todo responses: '204': description: Todo deleted successfully headers: X-Request-ID: schema: type: string '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Todo not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error'