openapi-documentation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenAPI Documentation Expert

OpenAPI文档专家

Expert in creating comprehensive OpenAPI/Swagger specifications and API documentation aligned with OpenAPI 3.0+ standards.
精通创建符合OpenAPI 3.0+标准的全面OpenAPI/Swagger规范及API文档。

Core Principles

核心原则

Specification Standards

规范标准

  • Use OpenAPI 3.0.3 or 3.1.0
  • Consistent naming conventions (kebab-case for paths, camelCase for properties)
  • Organize endpoints through tags
  • Maintain reusable component schemas
  • Document all response codes
  • 使用OpenAPI 3.0.3或3.1.0版本
  • 一致的命名约定(路径使用kebab-case,属性使用camelCase)
  • 通过标签组织端点
  • 维护可复用的组件模式
  • 记录所有响应码

Documentation Quality

文档质量

  • Provide business logic context
  • Include extensive realistic examples
  • Document all error scenarios
  • Define rate-limiting specifications
  • Explicit data format definitions
  • 提供业务逻辑上下文
  • 包含大量真实示例
  • 记录所有错误场景
  • 定义限流规范
  • 明确数据格式定义

OpenAPI 3.0 Structure

OpenAPI 3.0结构

Basic Specification

基础规范

yaml
openapi: "3.0.3"
info:
  title: "User Management API"
  description: |
    REST API for managing users in the platform.

    ## Authentication
    All endpoints require Bearer token authentication.

    ## Rate Limiting
    - Standard: 100 requests/minute
    - Premium: 1000 requests/minute

    ## Versioning
    API version is included in the URL path (/v1/).
  version: "1.0.0"
  contact:
    name: "API Support"
    email: "api-support@example.com"
    url: "https://developer.example.com/support"
  license:
    name: "Apache 2.0"
    url: "https://www.apache.org/licenses/LICENSE-2.0"
  termsOfService: "https://example.com/terms"

servers:
  - url: "https://api.example.com/v1"
    description: "Production server"
  - url: "https://staging-api.example.com/v1"
    description: "Staging server"
  - url: "http://localhost:3000/v1"
    description: "Development server"

tags:
  - name: "users"
    description: "User management operations"
  - name: "authentication"
    description: "Authentication and authorization"
  - name: "admin"
    description: "Administrative operations"

security:
  - bearerAuth: []
yaml
openapi: "3.0.3"
info:
  title: "User Management API"
  description: |
    REST API for managing users in the platform.

    ## Authentication
    All endpoints require Bearer token authentication.

    ## Rate Limiting
    - Standard: 100 requests/minute
    - Premium: 1000 requests/minute

    ## Versioning
    API version is included in the URL path (/v1/).
  version: "1.0.0"
  contact:
    name: "API Support"
    email: "api-support@example.com"
    url: "https://developer.example.com/support"
  license:
    name: "Apache 2.0"
    url: "https://www.apache.org/licenses/LICENSE-2.0"
  termsOfService: "https://example.com/terms"

servers:
  - url: "https://api.example.com/v1"
    description: "Production server"
  - url: "https://staging-api.example.com/v1"
    description: "Staging server"
  - url: "http://localhost:3000/v1"
    description: "Development server"

tags:
  - name: "users"
    description: "User management operations"
  - name: "authentication"
    description: "Authentication and authorization"
  - name: "admin"
    description: "Administrative operations"

security:
  - bearerAuth: []

Path Documentation

路径文档

yaml
paths:
  /users:
    get:
      operationId: "listUsers"
      tags:
        - "users"
      summary: "List all users"
      description: |
        Retrieve a paginated list of users.

        Results can be filtered by status and sorted by various fields.
        Pagination is cursor-based for optimal performance.
      parameters:
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageCursor"
        - name: "status"
          in: "query"
          description: "Filter by user status"
          required: false
          schema:
            type: "string"
            enum: ["active", "inactive", "pending"]
            default: "active"
        - name: "sort"
          in: "query"
          description: "Sort field and direction"
          required: false
          schema:
            type: "string"
            enum: ["created_at:asc", "created_at:desc", "name:asc", "name:desc"]
            default: "created_at:desc"
      responses:
        "200":
          description: "Successful response"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserListResponse"
              examples:
                success:
                  $ref: "#/components/examples/UserListSuccess"
          headers:
            X-RateLimit-Limit:
              $ref: "#/components/headers/X-RateLimit-Limit"
            X-RateLimit-Remaining:
              $ref: "#/components/headers/X-RateLimit-Remaining"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/TooManyRequests"

    post:
      operationId: "createUser"
      tags:
        - "users"
      summary: "Create a new user"
      description: |
        Create a new user account.

        A verification email will be sent to the provided email address.
        The user must verify their email before they can log in.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateUserRequest"
            examples:
              basic:
                summary: "Basic user creation"
                value:
                  email: "user@example.com"
                  name: "John Doe"
                  password: "SecurePassword123!"
              withProfile:
                summary: "User with profile data"
                value:
                  email: "user@example.com"
                  name: "John Doe"
                  password: "SecurePassword123!"
                  profile:
                    bio: "Software developer"
                    location: "San Francisco, CA"
      responses:
        "201":
          description: "User created successfully"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
              example:
                id: "usr_1234567890"
                email: "user@example.com"
                name: "John Doe"
                status: "pending"
                createdAt: "2024-03-15T10:30:00Z"
          headers:
            Location:
              description: "URL of the created user"
              schema:
                type: "string"
                format: "uri"
                example: "/users/usr_1234567890"
        "400":
          $ref: "#/components/responses/BadRequest"
        "409":
          description: "User already exists"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                code: "USER_EXISTS"
                message: "A user with this email already exists"
        "422":
          $ref: "#/components/responses/ValidationError"

  /users/{userId}:
    parameters:
      - $ref: "#/components/parameters/UserId"

    get:
      operationId: "getUser"
      tags:
        - "users"
      summary: "Get user by ID"
      description: "Retrieve detailed information about a specific user"
      responses:
        "200":
          description: "Successful response"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "404":
          $ref: "#/components/responses/NotFound"

    patch:
      operationId: "updateUser"
      tags:
        - "users"
      summary: "Update user"
      description: |
        Partially update a user's information.

        Only the fields provided in the request body will be updated.
        To remove a field, set it to null explicitly.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateUserRequest"
      responses:
        "200":
          description: "User updated successfully"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/NotFound"

    delete:
      operationId: "deleteUser"
      tags:
        - "users"
      summary: "Delete user"
      description: |
        Permanently delete a user account.

        This action cannot be undone. All associated data will be removed.
      responses:
        "204":
          description: "User deleted successfully"
        "404":
          $ref: "#/components/responses/NotFound"
yaml
paths:
  /users:
    get:
      operationId: "listUsers"
      tags:
        - "users"
      summary: "List all users"
      description: |
        Retrieve a paginated list of users.

        Results can be filtered by status and sorted by various fields.
        Pagination is cursor-based for optimal performance.
      parameters:
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageCursor"
        - name: "status"
          in: "query"
          description: "Filter by user status"
          required: false
          schema:
            type: "string"
            enum: ["active", "inactive", "pending"]
            default: "active"
        - name: "sort"
          in: "query"
          description: "Sort field and direction"
          required: false
          schema:
            type: "string"
            enum: ["created_at:asc", "created_at:desc", "name:asc", "name:desc"]
            default: "created_at:desc"
      responses:
        "200":
          description: "Successful response"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserListResponse"
              examples:
                success:
                  $ref: "#/components/examples/UserListSuccess"
          headers:
            X-RateLimit-Limit:
              $ref: "#/components/headers/X-RateLimit-Limit"
            X-RateLimit-Remaining:
              $ref: "#/components/headers/X-RateLimit-Remaining"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/TooManyRequests"

    post:
      operationId: "createUser"
      tags:
        - "users"
      summary: "Create a new user"
      description: |
        Create a new user account.

        A verification email will be sent to the provided email address.
        The user must verify their email before they can log in.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateUserRequest"
            examples:
              basic:
                summary: "Basic user creation"
                value:
                  email: "user@example.com"
                  name: "John Doe"
                  password: "SecurePassword123!"
              withProfile:
                summary: "User with profile data"
                value:
                  email: "user@example.com"
                  name: "John Doe"
                  password: "SecurePassword123!"
                  profile:
                    bio: "Software developer"
                    location: "San Francisco, CA"
      responses:
        "201":
          description: "User created successfully"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
              example:
                id: "usr_1234567890"
                email: "user@example.com"
                name: "John Doe"
                status: "pending"
                createdAt: "2024-03-15T10:30:00Z"
          headers:
            Location:
              description: "URL of the created user"
              schema:
                type: "string"
                format: "uri"
                example: "/users/usr_1234567890"
        "400":
          $ref: "#/components/responses/BadRequest"
        "409":
          description: "User already exists"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                code: "USER_EXISTS"
                message: "A user with this email already exists"
        "422":
          $ref: "#/components/responses/ValidationError"

  /users/{userId}:
    parameters:
      - $ref: "#/components/parameters/UserId"

    get:
      operationId: "getUser"
      tags:
        - "users"
      summary: "Get user by ID"
      description: "Retrieve detailed information about a specific user"
      responses:
        "200":
          description: "Successful response"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "404":
          $ref: "#/components/responses/NotFound"

    patch:
      operationId: "updateUser"
      tags:
        - "users"
      summary: "Update user"
      description: |
        Partially update a user's information.

        Only the fields provided in the request body will be updated.
        To remove a field, set it to null explicitly.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateUserRequest"
      responses:
        "200":
          description: "User updated successfully"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/NotFound"

    delete:
      operationId: "deleteUser"
      tags:
        - "users"
      summary: "Delete user"
      description: |
        Permanently delete a user account.

        This action cannot be undone. All associated data will be removed.
      responses:
        "204":
          description: "User deleted successfully"
        "404":
          $ref: "#/components/responses/NotFound"

Components

组件

yaml
components:
  schemas:
    User:
      type: "object"
      description: "User account information"
      required:
        - "id"
        - "email"
        - "name"
        - "status"
        - "createdAt"
      properties:
        id:
          type: "string"
          description: "Unique user identifier"
          pattern: "^usr_[a-zA-Z0-9]{10}$"
          example: "usr_1234567890"
          readOnly: true
        email:
          type: "string"
          format: "email"
          description: "User's email address"
          example: "user@example.com"
        name:
          type: "string"
          description: "User's display name"
          minLength: 1
          maxLength: 100
          example: "John Doe"
        status:
          type: "string"
          description: "Account status"
          enum: ["active", "inactive", "pending", "suspended"]
          example: "active"
        profile:
          $ref: "#/components/schemas/UserProfile"
        createdAt:
          type: "string"
          format: "date-time"
          description: "Account creation timestamp"
          readOnly: true
          example: "2024-03-15T10:30:00Z"
        updatedAt:
          type: "string"
          format: "date-time"
          description: "Last update timestamp"
          readOnly: true
          example: "2024-03-15T10:30:00Z"

    UserProfile:
      type: "object"
      description: "Extended user profile information"
      properties:
        bio:
          type: "string"
          description: "User biography"
          maxLength: 500
          example: "Software developer passionate about APIs"
        location:
          type: "string"
          description: "User's location"
          maxLength: 100
          example: "San Francisco, CA"
        avatarUrl:
          type: "string"
          format: "uri"
          description: "URL to user's avatar image"
          example: "https://cdn.example.com/avatars/usr_123.jpg"
        timezone:
          type: "string"
          description: "User's timezone"
          example: "America/Los_Angeles"

    CreateUserRequest:
      type: "object"
      description: "Request body for creating a new user"
      required:
        - "email"
        - "name"
        - "password"
      properties:
        email:
          type: "string"
          format: "email"
          description: "User's email address"
          example: "user@example.com"
        name:
          type: "string"
          description: "User's display name"
          minLength: 1
          maxLength: 100
          example: "John Doe"
        password:
          type: "string"
          format: "password"
          description: "User's password"
          minLength: 8
          maxLength: 128
          pattern: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"
          example: "SecurePassword123!"
        profile:
          $ref: "#/components/schemas/UserProfile"

    UpdateUserRequest:
      type: "object"
      description: "Request body for updating a user"
      properties:
        name:
          type: "string"
          description: "User's display name"
          minLength: 1
          maxLength: 100
          nullable: true
        profile:
          $ref: "#/components/schemas/UserProfile"

    UserListResponse:
      type: "object"
      description: "Paginated list of users"
      required:
        - "data"
        - "pagination"
      properties:
        data:
          type: "array"
          items:
            $ref: "#/components/schemas/User"
        pagination:
          $ref: "#/components/schemas/Pagination"

    Pagination:
      type: "object"
      description: "Pagination metadata"
      required:
        - "total"
        - "hasMore"
      properties:
        total:
          type: "integer"
          description: "Total number of items"
          example: 150
        hasMore:
          type: "boolean"
          description: "Whether more items exist"
          example: true
        nextCursor:
          type: "string"
          description: "Cursor for next page"
          example: "eyJpZCI6MTAwfQ=="
        prevCursor:
          type: "string"
          description: "Cursor for previous page"
          example: "eyJpZCI6NTB9"

    Error:
      type: "object"
      description: "Error response"
      required:
        - "code"
        - "message"
      properties:
        code:
          type: "string"
          description: "Machine-readable error code"
          example: "VALIDATION_ERROR"
        message:
          type: "string"
          description: "Human-readable error message"
          example: "The request body is invalid"
        details:
          type: "array"
          description: "Detailed error information"
          items:
            type: "object"
            properties:
              field:
                type: "string"
                description: "Field that caused the error"
                example: "email"
              message:
                type: "string"
                description: "Error message for this field"
                example: "Must be a valid email address"
        requestId:
          type: "string"
          description: "Request ID for support"
          example: "req_abc123xyz"
        timestamp:
          type: "string"
          format: "date-time"
          description: "Error timestamp"
          example: "2024-03-15T10:30:00Z"

  parameters:
    UserId:
      name: "userId"
      in: "path"
      description: "User ID"
      required: true
      schema:
        type: "string"
        pattern: "^usr_[a-zA-Z0-9]{10}$"
      example: "usr_1234567890"

    PageSize:
      name: "limit"
      in: "query"
      description: "Number of items per page"
      required: false
      schema:
        type: "integer"
        minimum: 1
        maximum: 100
        default: 20

    PageCursor:
      name: "cursor"
      in: "query"
      description: "Pagination cursor"
      required: false
      schema:
        type: "string"

  headers:
    X-RateLimit-Limit:
      description: "Request limit per minute"
      schema:
        type: "integer"
      example: 100

    X-RateLimit-Remaining:
      description: "Remaining requests in current window"
      schema:
        type: "integer"
      example: 95

    X-RateLimit-Reset:
      description: "Unix timestamp when limit resets"
      schema:
        type: "integer"
      example: 1710500000

  responses:
    BadRequest:
      description: "Bad request"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "BAD_REQUEST"
            message: "The request could not be processed"
            requestId: "req_abc123xyz"

    Unauthorized:
      description: "Authentication required"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "UNAUTHORIZED"
            message: "Authentication credentials are missing or invalid"

    NotFound:
      description: "Resource not found"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "NOT_FOUND"
            message: "The requested resource was not found"

    ValidationError:
      description: "Validation error"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "VALIDATION_ERROR"
            message: "Request validation failed"
            details:
              - field: "email"
                message: "Must be a valid email address"
              - field: "password"
                message: "Must be at least 8 characters"

    TooManyRequests:
      description: "Rate limit exceeded"
      headers:
        Retry-After:
          description: "Seconds until rate limit resets"
          schema:
            type: "integer"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "RATE_LIMIT_EXCEEDED"
            message: "Too many requests. Please try again later."

  securitySchemes:
    bearerAuth:
      type: "http"
      scheme: "bearer"
      bearerFormat: "JWT"
      description: |
        JWT authentication token.

        Include in the Authorization header:
        `Authorization: Bearer <token>`

        Tokens expire after 1 hour. Use the refresh token endpoint
        to obtain a new access token.

    apiKey:
      type: "apiKey"
      in: "header"
      name: "X-API-Key"
      description: "API key for server-to-server communication"

  examples:
    UserListSuccess:
      summary: "Successful user list"
      value:
        data:
          - id: "usr_1234567890"
            email: "user1@example.com"
            name: "John Doe"
            status: "active"
            createdAt: "2024-03-15T10:30:00Z"
          - id: "usr_0987654321"
            email: "user2@example.com"
            name: "Jane Smith"
            status: "active"
            createdAt: "2024-03-14T09:00:00Z"
        pagination:
          total: 150
          hasMore: true
          nextCursor: "eyJpZCI6MTAwfQ=="
yaml
components:
  schemas:
    User:
      type: "object"
      description: "User account information"
      required:
        - "id"
        - "email"
        - "name"
        - "status"
        - "createdAt"
      properties:
        id:
          type: "string"
          description: "Unique user identifier"
          pattern: "^usr_[a-zA-Z0-9]{10}$"
          example: "usr_1234567890"
          readOnly: true
        email:
          type: "string"
          format: "email"
          description: "User's email address"
          example: "user@example.com"
        name:
          type: "string"
          description: "User's display name"
          minLength: 1
          maxLength: 100
          example: "John Doe"
        status:
          type: "string"
          description: "Account status"
          enum: ["active", "inactive", "pending", "suspended"]
          example: "active"
        profile:
          $ref: "#/components/schemas/UserProfile"
        createdAt:
          type: "string"
          format: "date-time"
          description: "Account creation timestamp"
          readOnly: true
          example: "2024-03-15T10:30:00Z"
        updatedAt:
          type: "string"
          format: "date-time"
          description: "Last update timestamp"
          readOnly: true
          example: "2024-03-15T10:30:00Z"

    UserProfile:
      type: "object"
      description: "Extended user profile information"
      properties:
        bio:
          type: "string"
          description: "User biography"
          maxLength: 500
          example: "Software developer passionate about APIs"
        location:
          type: "string"
          description: "User's location"
          maxLength: 100
          example: "San Francisco, CA"
        avatarUrl:
          type: "string"
          format: "uri"
          description: "URL to user's avatar image"
          example: "https://cdn.example.com/avatars/usr_123.jpg"
        timezone:
          type: "string"
          description: "User's timezone"
          example: "America/Los_Angeles"

    CreateUserRequest:
      type: "object"
      description: "Request body for creating a new user"
      required:
        - "email"
        - "name"
        - "password"
      properties:
        email:
          type: "string"
          format: "email"
          description: "User's email address"
          example: "user@example.com"
        name:
          type: "string"
          description: "User's display name"
          minLength: 1
          maxLength: 100
          example: "John Doe"
        password:
          type: "string"
          format: "password"
          description: "User's password"
          minLength: 8
          maxLength: 128
          pattern: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"
          example: "SecurePassword123!"
        profile:
          $ref: "#/components/schemas/UserProfile"

    UpdateUserRequest:
      type: "object"
      description: "Request body for updating a user"
      properties:
        name:
          type: "string"
          description: "User's display name"
          minLength: 1
          maxLength: 100
          nullable: true
        profile:
          $ref: "#/components/schemas/UserProfile"

    UserListResponse:
      type: "object"
      description: "Paginated list of users"
      required:
        - "data"
        - "pagination"
      properties:
        data:
          type: "array"
          items:
            $ref: "#/components/schemas/User"
        pagination:
          $ref: "#/components/schemas/Pagination"

    Pagination:
      type: "object"
      description: "Pagination metadata"
      required:
        - "total"
        - "hasMore"
      properties:
        total:
          type: "integer"
          description: "Total number of items"
          example: 150
        hasMore:
          type: "boolean"
          description: "Whether more items exist"
          example: true
        nextCursor:
          type: "string"
          description: "Cursor for next page"
          example: "eyJpZCI6MTAwfQ=="
        prevCursor:
          type: "string"
          description: "Cursor for previous page"
          example: "eyJpZCI6NTB9"

    Error:
      type: "object"
      description: "Error response"
      required:
        - "code"
        - "message"
      properties:
        code:
          type: "string"
          description: "Machine-readable error code"
          example: "VALIDATION_ERROR"
        message:
          type: "string"
          description: "Human-readable error message"
          example: "The request body is invalid"
        details:
          type: "array"
          description: "Detailed error information"
          items:
            type: "object"
            properties:
              field:
                type: "string"
                description: "Field that caused the error"
                example: "email"
              message:
                type: "string"
                description: "Error message for this field"
                example: "Must be a valid email address"
        requestId:
          type: "string"
          description: "Request ID for support"
          example: "req_abc123xyz"
        timestamp:
          type: "string"
          format: "date-time"
          description: "Error timestamp"
          example: "2024-03-15T10:30:00Z"

  parameters:
    UserId:
      name: "userId"
      in: "path"
      description: "User ID"
      required: true
      schema:
        type: "string"
        pattern: "^usr_[a-zA-Z0-9]{10}$"
      example: "usr_1234567890"

    PageSize:
      name: "limit"
      in: "query"
      description: "Number of items per page"
      required: false
      schema:
        type: "integer"
        minimum: 1
        maximum: 100
        default: 20

    PageCursor:
      name: "cursor"
      in: "query"
      description: "Pagination cursor"
      required: false
      schema:
        type: "string"

  headers:
    X-RateLimit-Limit:
      description: "Request limit per minute"
      schema:
        type: "integer"
      example: 100

    X-RateLimit-Remaining:
      description: "Remaining requests in current window"
      schema:
        type: "integer"
      example: 95

    X-RateLimit-Reset:
      description: "Unix timestamp when limit resets"
      schema:
        type: "integer"
      example: 1710500000

  responses:
    BadRequest:
      description: "Bad request"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "BAD_REQUEST"
            message: "The request could not be processed"
            requestId: "req_abc123xyz"

    Unauthorized:
      description: "Authentication required"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "UNAUTHORIZED"
            message: "Authentication credentials are missing or invalid"

    NotFound:
      description: "Resource not found"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "NOT_FOUND"
            message: "The requested resource was not found"

    ValidationError:
      description: "Validation error"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "VALIDATION_ERROR"
            message: "Request validation failed"
            details:
              - field: "email"
                message: "Must be a valid email address"
              - field: "password"
                message: "Must be at least 8 characters"

    TooManyRequests:
      description: "Rate limit exceeded"
      headers:
        Retry-After:
          description: "Seconds until rate limit resets"
          schema:
            type: "integer"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "RATE_LIMIT_EXCEEDED"
            message: "Too many requests. Please try again later."

  securitySchemes:
    bearerAuth:
      type: "http"
      scheme: "bearer"
      bearerFormat: "JWT"
      description: |
        JWT authentication token.

        Include in the Authorization header:
        `Authorization: Bearer <token>`

        Tokens expire after 1 hour. Use the refresh token endpoint
        to obtain a new access token.

    apiKey:
      type: "apiKey"
      in: "header"
      name: "X-API-Key"
      description: "API key for server-to-server communication"

  examples:
    UserListSuccess:
      summary: "Successful user list"
      value:
        data:
          - id: "usr_1234567890"
            email: "user1@example.com"
            name: "John Doe"
            status: "active"
            createdAt: "2024-03-15T10:30:00Z"
          - id: "usr_0987654321"
            email: "user2@example.com"
            name: "Jane Smith"
            status: "active"
            createdAt: "2024-03-14T09:00:00Z"
        pagination:
          total: 150
          hasMore: true
          nextCursor: "eyJpZCI6MTAwfQ=="

Advanced Features

高级特性

Webhooks (OpenAPI 3.1)

Webhooks (OpenAPI 3.1)

yaml
webhooks:
  userCreated:
    post:
      operationId: "userCreatedWebhook"
      summary: "User created event"
      description: |
        Triggered when a new user account is created.

        Your endpoint must respond with a 2xx status code within 30 seconds.
        Failed deliveries will be retried up to 5 times with exponential backoff.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              required:
                - "event"
                - "timestamp"
                - "data"
              properties:
                event:
                  type: "string"
                  const: "user.created"
                timestamp:
                  type: "string"
                  format: "date-time"
                data:
                  $ref: "#/components/schemas/User"
      responses:
        "200":
          description: "Webhook received successfully"
      security:
        - webhookSignature: []

  userUpdated:
    post:
      operationId: "userUpdatedWebhook"
      summary: "User updated event"
      description: "Triggered when a user's information is modified"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                event:
                  type: "string"
                  const: "user.updated"
                timestamp:
                  type: "string"
                  format: "date-time"
                data:
                  type: "object"
                  properties:
                    user:
                      $ref: "#/components/schemas/User"
                    changes:
                      type: "object"
                      description: "Fields that were changed"
      responses:
        "200":
          description: "Webhook received successfully"
yaml
webhooks:
  userCreated:
    post:
      operationId: "userCreatedWebhook"
      summary: "User created event"
      description: |
        Triggered when a new user account is created.

        Your endpoint must respond with a 2xx status code within 30 seconds.
        Failed deliveries will be retried up to 5 times with exponential backoff.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              required:
                - "event"
                - "timestamp"
                - "data"
              properties:
                event:
                  type: "string"
                  const: "user.created"
                timestamp:
                  type: "string"
                  format: "date-time"
                data:
                  $ref: "#/components/schemas/User"
      responses:
        "200":
          description: "Webhook received successfully"
      security:
        - webhookSignature: []

  userUpdated:
    post:
      operationId: "userUpdatedWebhook"
      summary: "User updated event"
      description: "Triggered when a user's information is modified"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                event:
                  type: "string"
                  const: "user.updated"
                timestamp:
                  type: "string"
                  format: "date-time"
                data:
                  type: "object"
                  properties:
                    user:
                      $ref: "#/components/schemas/User"
                    changes:
                      type: "object"
                      description: "Fields that were changed"
      responses:
        "200":
          description: "Webhook received successfully"

Custom Extensions

自定义扩展

yaml
x-code-samples:
  - lang: "curl"
    label: "cURL"
    source: |
      curl -X GET "https://api.example.com/v1/users" \
        -H "Authorization: Bearer your_token_here" \
        -H "Accept: application/json"

  - lang: "javascript"
    label: "JavaScript"
    source: |
      const response = await fetch('https://api.example.com/v1/users', {
        headers: {
          'Authorization': 'Bearer your_token_here',
          'Accept': 'application/json'
        }
      });
      const users = await response.json();

  - lang: "python"
    label: "Python"
    source: |
      import requests

      response = requests.get(
          'https://api.example.com/v1/users',
          headers={'Authorization': 'Bearer your_token_here'}
      )
      users = response.json()

x-rate-limiting:
  standard:
    limit: 100
    window: "1 minute"
  premium:
    limit: 1000
    window: "1 minute"

x-changelog:
  - version: "1.0.0"
    date: "2024-03-15"
    changes:
      - "Initial release"
  - version: "1.1.0"
    date: "2024-04-01"
    changes:
      - "Added user profile endpoints"
      - "Added pagination support"
yaml
x-code-samples:
  - lang: "curl"
    label: "cURL"
    source: |
      curl -X GET "https://api.example.com/v1/users" \
        -H "Authorization: Bearer your_token_here" \
        -H "Accept: application/json"

  - lang: "javascript"
    label: "JavaScript"
    source: |
      const response = await fetch('https://api.example.com/v1/users', {
        headers: {
          'Authorization': 'Bearer your_token_here',
          'Accept': 'application/json'
        }
      });
      const users = await response.json();

  - lang: "python"
    label: "Python"
    source: |
      import requests

      response = requests.get(
          'https://api.example.com/v1/users',
          headers={'Authorization': 'Bearer your_token_here'}
      )
      users = response.json()

x-rate-limiting:
  standard:
    limit: 100
    window: "1 minute"
  premium:
    limit: 1000
    window: "1 minute"

x-changelog:
  - version: "1.0.0"
    date: "2024-03-15"
    changes:
      - "Initial release"
  - version: "1.1.0"
    date: "2024-04-01"
    changes:
      - "Added user profile endpoints"
      - "Added pagination support"

Validation & Quality

验证与质量

Schema Validation Rules

模式验证规则

yaml
validation_patterns:
  strings:
    email:
      format: "email"
      maxLength: 254

    uuid:
      format: "uuid"
      pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"

    phone:
      pattern: "^\\+[1-9]\\d{1,14}$"

    url:
      format: "uri"
      pattern: "^https?://"

  numbers:
    positive_integer:
      type: "integer"
      minimum: 1

    percentage:
      type: "number"
      minimum: 0
      maximum: 100

    currency:
      type: "number"
      multipleOf: 0.01
      minimum: 0

  dates:
    date_only:
      type: "string"
      format: "date"
      pattern: "^\\d{4}-\\d{2}-\\d{2}$"

    datetime:
      type: "string"
      format: "date-time"

  arrays:
    non_empty_array:
      type: "array"
      minItems: 1

    unique_array:
      type: "array"
      uniqueItems: true
yaml
validation_patterns:
  strings:
    email:
      format: "email"
      maxLength: 254

    uuid:
      format: "uuid"
      pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"

    phone:
      pattern: "^\\+[1-9]\\d{1,14}$"

    url:
      format: "uri"
      pattern: "^https?://"

  numbers:
    positive_integer:
      type: "integer"
      minimum: 1

    percentage:
      type: "number"
      minimum: 0
      maximum: 100

    currency:
      type: "number"
      multipleOf: 0.01
      minimum: 0

  dates:
    date_only:
      type: "string"
      format: "date"
      pattern: "^\\d{4}-\\d{2}-\\d{2}$"

    datetime:
      type: "string"
      format: "date-time"

  arrays:
    non_empty_array:
      type: "array"
      minItems: 1

    unique_array:
      type: "array"
      uniqueItems: true

Linting Configuration

代码检查配置

yaml
undefined
yaml
undefined

.spectral.yaml

.spectral.yaml

extends: ["spectral:oas"]
rules:

Naming conventions

operation-operationId-valid-in-url: true path-keys-no-trailing-slash: true

Documentation requirements

operation-description: true operation-tag-defined: true info-contact: true

Schema quality

oas3-schema: true typed-enum: true

Custom rules

operation-summary-length: description: "Operation summary should be concise" severity: warn given: "$.paths.*[get,post,put,patch,delete]" then: field: "summary" function: length functionOptions: max: 80
must-have-examples: description: "Responses should have examples" severity: warn given: "$.paths...responses..content." then: field: "examples" function: truthy
undefined
extends: ["spectral:oas"]
rules:

Naming conventions

operation-operationId-valid-in-url: true path-keys-no-trailing-slash: true

Documentation requirements

operation-description: true operation-tag-defined: true info-contact: true

Schema quality

oas3-schema: true typed-enum: true

Custom rules

operation-summary-length: description: "Operation summary should be concise" severity: warn given: "$.paths.*[get,post,put,patch,delete]" then: field: "summary" function: length functionOptions: max: 80
must-have-examples: description: "Responses should have examples" severity: warn given: "$.paths...responses..content." then: field: "examples" function: truthy
undefined

Code Generation

代码生成

Generator Configuration

生成器配置

yaml
undefined
yaml
undefined

openapi-generator-cli.yaml

openapi-generator-cli.yaml

spaces: 2
generators: typescript-axios: inputSpec: ./api/openapi.yaml output: ./generated/typescript-client generatorName: typescript-axios additionalProperties: npmName: "@example/api-client" supportsES6: true withInterfaces: true withSeparateModelsAndApi: true
python-client: inputSpec: ./api/openapi.yaml output: ./generated/python-client generatorName: python additionalProperties: packageName: "example_api_client" projectName: "example-api-client"
go-server: inputSpec: ./api/openapi.yaml output: ./generated/go-server generatorName: go-server additionalProperties: packageName: "api" serverPort: 8080
undefined
spaces: 2
generators: typescript-axios: inputSpec: ./api/openapi.yaml output: ./generated/typescript-client generatorName: typescript-axios additionalProperties: npmName: "@example/api-client" supportsES6: true withInterfaces: true withSeparateModelsAndApi: true
python-client: inputSpec: ./api/openapi.yaml output: ./generated/python-client generatorName: python additionalProperties: packageName: "example_api_client" projectName: "example-api-client"
go-server: inputSpec: ./api/openapi.yaml output: ./generated/go-server generatorName: go-server additionalProperties: packageName: "api" serverPort: 8080
undefined

SDK Generation Script

SDK生成脚本

bash
#!/bin/bash
bash
#!/bin/bash

generate-sdks.sh

generate-sdks.sh

SPEC_FILE="./api/openapi.yaml" OUTPUT_DIR="./generated"
SPEC_FILE="./api/openapi.yaml" OUTPUT_DIR="./generated"

Validate spec first

Validate spec first

npx @redocly/cli lint $SPEC_FILE
if [ $? -ne 0 ]; then echo "Spec validation failed" exit 1 fi
npx @redocly/cli lint $SPEC_FILE
if [ $? -ne 0 ]; then echo "Spec validation failed" exit 1 fi

Generate TypeScript client

Generate TypeScript client

npx openapi-generator-cli generate
-i $SPEC_FILE
-g typescript-axios
-o $OUTPUT_DIR/typescript
--additional-properties=npmName=@example/api-client,supportsES6=true
npx openapi-generator-cli generate
-i $SPEC_FILE
-g typescript-axios
-o $OUTPUT_DIR/typescript
--additional-properties=npmName=@example/api-client,supportsES6=true

Generate Python client

Generate Python client

npx openapi-generator-cli generate
-i $SPEC_FILE
-g python
-o $OUTPUT_DIR/python
--additional-properties=packageName=example_api
echo "SDK generation complete"
undefined
npx openapi-generator-cli generate
-i $SPEC_FILE
-g python
-o $OUTPUT_DIR/python
--additional-properties=packageName=example_api
echo "SDK generation complete"
undefined

Documentation Tools

文档工具

Redoc Configuration

Redoc配置

yaml
undefined
yaml
undefined

redoc.yaml

redoc.yaml

openapi: "./api/openapi.yaml" output: "./docs/index.html"
options: theme: colors: primary: main: "#1976d2" typography: fontSize: "15px" fontFamily: "Inter, sans-serif" code: fontSize: "13px" fontFamily: "JetBrains Mono, monospace"
hideDownloadButton: false hideHostname: false pathInMiddlePanel: true requiredPropsFirst: true sortPropsAlphabetically: false hideLoading: false nativeScrollbars: true
jsonSampleExpandLevel: 2 enumSkipQuotes: false showExtensions: true
undefined
openapi: "./api/openapi.yaml" output: "./docs/index.html"
options: theme: colors: primary: main: "#1976d2" typography: fontSize: "15px" fontFamily: "Inter, sans-serif" code: fontSize: "13px" fontFamily: "JetBrains Mono, monospace"
hideDownloadButton: false hideHostname: false pathInMiddlePanel: true requiredPropsFirst: true sortPropsAlphabetically: false hideLoading: false nativeScrollbars: true
jsonSampleExpandLevel: 2 enumSkipQuotes: false showExtensions: true
undefined

Swagger UI Configuration

Swagger UI配置

javascript
// swagger-ui-config.js
const swaggerUiOptions = {
  dom_id: '#swagger-ui',
  url: '/api/openapi.yaml',

  // Display options
  deepLinking: true,
  displayOperationId: false,
  defaultModelsExpandDepth: 2,
  defaultModelExpandDepth: 2,
  displayRequestDuration: true,
  docExpansion: 'list',
  filter: true,
  showExtensions: true,
  showCommonExtensions: true,

  // Try it out configuration
  tryItOutEnabled: true,
  supportedSubmitMethods: ['get', 'post', 'put', 'patch', 'delete'],

  // Request interceptor for auth
  requestInterceptor: (request) => {
    const token = localStorage.getItem('api_token');
    if (token) {
      request.headers.Authorization = `Bearer ${token}`;
    }
    return request;
  },

  // Plugins
  plugins: [
    SwaggerUIBundle.plugins.DownloadUrl
  ],

  // Layout
  layout: "StandaloneLayout",
  presets: [
    SwaggerUIBundle.presets.apis,
    SwaggerUIStandalonePreset
  ]
};
javascript
// swagger-ui-config.js
const swaggerUiOptions = {
  dom_id: '#swagger-ui',
  url: '/api/openapi.yaml',

  // Display options
  deepLinking: true,
  displayOperationId: false,
  defaultModelsExpandDepth: 2,
  defaultModelExpandDepth: 2,
  displayRequestDuration: true,
  docExpansion: 'list',
  filter: true,
  showExtensions: true,
  showCommonExtensions: true,

  // Try it out configuration
  tryItOutEnabled: true,
  supportedSubmitMethods: ['get', 'post', 'put', 'patch', 'delete'],

  // Request interceptor for auth
  requestInterceptor: (request) => {
    const token = localStorage.getItem('api_token');
    if (token) {
      request.headers.Authorization = `Bearer ${token}`;
    }
    return request;
  },

  // Plugins
  plugins: [
    SwaggerUIBundle.plugins.DownloadUrl
  ],

  // Layout
  layout: "StandaloneLayout",
  presets: [
    SwaggerUIBundle.presets.apis,
    SwaggerUIStandalonePreset
  ]
};

Лучшие практики

最佳实践

  1. Version everything — используйте семантическое версионирование
  2. Examples for all — добавляйте реалистичные примеры для всех схем
  3. Error documentation — документируйте все возможные коды ошибок
  4. Consistent naming — kebab-case для paths, camelCase для properties
  5. Reusable components — выносите общие схемы в components
  6. Validate specs — используйте линтеры (Spectral, Redocly)
  1. 版本化所有内容 — 使用语义化版本控制
  2. 为所有内容添加示例 — 为所有模式添加真实示例
  3. 错误文档 — 记录所有可能的错误代码
  4. 命名一致性 — 路径使用kebab-case,属性使用camelCase
  5. 可复用组件 — 将通用模式提取到components中
  6. 验证规范 — 使用代码检查工具(Spectral、Redocly)