foo/test.md
Sandipsinh Rathod fe3ec74e35 init
2024-12-19 19:42:36 -05:00

13 KiB

Example for OpenAPI

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: array
          items:
            $ref: '#/components/schemas/Todo'
        metadata:
          type: object
          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:
          $ref: '#/components/schemas/Todo'
      required:
        - data

    Error:
      type: object
      properties:
        error:
          type: object
          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'
package api:todos@1.0.0;

// Common types used across the API
interface types {
    // Authentication types derived from OpenAPI security schemes
    record bearer-token {
        token: string,
    }

    // Core resource type
    record todo {
        id: string,
        title: string,
        description: option<string>,
        completed: bool,
        due-date: option<string>,
        user-id: string,
        created-at: string,
        updated-at: string,
    }

    variant error {
        unauthorized,
        not-found,
        validation-error(list<string>),
        rate-limited { retry-after: u32 },
        server-error,
    }
}

interface todos-collection {
    use types.{todo, bearer-token, error};

    // Request/response types with domain-appropriate fields
    record list-request {
        auth: bearer-token,
        user-id: string,
        status: option<string>,
        limit: option<u32>,
        %offset: option<u32>,
    }

    record list-response {
        items: list<todo>,
        total: u32,
        limit: u32,
        %offset: u32,
        version: string,  // From ETag
        last-updated: option<string>,  // From Last-Modified
    }

    record create-request {
        auth: bearer-token,
        title: string,
        description: option<string>,
        due-date: option<string>,
        user-id: string,
    }

    // Note: Response includes versioning info directly in return type
    list: func(request: list-request) -> result<list-response, error>;
    
    create: func(request: create-request) -> result<todo, error>;
}

interface todos-resource {
    use types.{todo, bearer-token, error};

    record update-request {
        auth: bearer-token,
        title: option<string>,
        description: option<string>,
        completed: option<bool>,
        due-date: option<string>,
        expected-version: option<string>,  // If-Match header
    }

    get: func(id: string, auth: bearer-token) -> result<todo, error>;
    
    update: func(id: string, request: update-request) -> result<todo, error>;
    
    delete: func(id: string, auth: bearer-token) -> result<unit, error>;
}

world todos-api {
    export todos-collection;
    export todos-resource;
}