mcpField
O
openapi-spec-writer

openapi-spec-writer

github.com/curiositech开发257164 次安装2 天前更新
代码仓库

关于 openapi-spec-writer

用于编写 REST API 的 OpenAPI 3.0/3.1 规范的开发技能,支持 API 设计与文档编写、Schema 组合,以及配置校验、交互式文档、模拟服务和 SDK 生成。

主要功能

  1. 01编写 OpenAPI 3.0 和 3.1
  2. 02设计可复用及组合式 Schema
  3. 03提供请求与响应示例
  4. 04记录身份验证和错误响应
  5. 05配置规范校验与文档工具
  6. 06配置 SDK 和模拟服务生成

适用场景

  1. 01定义新的 REST API 契约
  2. 02为现有 API 编写文档
  3. 03根据规范生成 SDK
  4. 04迁移 Swagger 2.0 规范

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/curiositech/some_claude_skills --skill openapi-spec-writer

安装后在 Claude Code 中输入/openapi-spec-writer确认已加载。

附带文件.claude-plugin/plugin.json

详细介绍

OpenAPI 规范编写器

概述

擅长为 REST API 编写 OpenAPI 3.0/3.1 规范。专精于架构设计、文档最佳实践、API 优先开发和工具集成。生成全面的 API 文档,使其兼具文档和契约的作用。

适用场景

  • 为新 API 创建 OpenAPI 规范
  • 为现有 REST API 编写文档
  • 在实施前设计 API 契约
  • 根据规范生成客户端 SDK
  • 设置交互式 API 文档(Swagger UI、Redoc)
  • 根据架构验证 API 响应
  • 从 OpenAPI 2.0(Swagger)迁移到 3.x

能力

规范编写
  • OpenAPI 3.0 和 3.1 语法
  • 路径和操作定义
  • 请求/响应架构
  • 身份验证方案
  • 服务配置
架构设计
  • 带有 OpenAPI 扩展的 JSON Schema
  • 可复用的组件架构
  • 用于多态的判别器
  • oneOf、anyOf、allOf 组合
  • 可空类型和默认值
文档质量
  • 有意义的描述和示例
  • 描述中的 Markdown
  • 请求/响应示例
  • 错误响应文档
  • 弃用通知
工具集成
  • Swagger UI 配置
  • Redoc 自定义
  • Spectral lint 规则
  • SDK 生成设置
  • Mock 服务配置

依赖项

可与以下工具配合使用:

  • api-architect - API 设计模式
  • rest-api-design - RESTful 约定
  • typescript-pro - 生成客户端类型
  • github-actions-pipeline-builder - CI 验证

示例

完整的 OpenAPI 3.1 规范
openapi: 3.1.0
info:
  title: Task Management API
  description: |
    RESTful API for managing tasks and projects.

    ## Authentication
    All endpoints require a Bearer token in the Authorization header.

    ## Rate Limiting
    - 1000 requests per hour per API key
    - Rate limit headers included in all responses
  version: 1.0.0
  contact:
    name: API Support
    email: [email protected]
    url: https://docs.example.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

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: Local development

tags:
  - name: Tasks
    description: Task management operations
  - name: Projects
    description: Project management operations

paths:
  /tasks:
    get:
      operationId: listTasks
      summary: List all tasks
      description: Returns a paginated list of tasks with optional filtering.
      tags:
        - Tasks
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: status
          in: query
          description: Filter by task status
          schema:
            $ref: '#/components/schemas/TaskStatus'
        - name: project_id
          in: query
          description: Filter by project ID
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskListResponse'
              examples:
                default:
                  $ref: '#/components/examples/TaskListExample'
          headers:
            X-Total-Count:
              schema:
                type: integer
              description: Total number of tasks matching the query
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      operationId: createTask
      summary: Create a new task
      description: Creates a new task and returns the created resource.
      tags:
        - Tasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTaskRequest'
            examples:
              minimal:
                summary: Minimal task
                value:
                  title: "Complete documentation"
              full:
                summary: Full task with all fields
                value:
                  title: "Complete documentation"
                  description: "Write API docs for v1.0"
                  project_id: "550e8400-e29b-41d4-a716-446655440000"
                  due_date: "2024-12-31"
                  priority: "high"
      responses:
        '201':
          description: Task created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
          headers:
            Location:
              schema:
                type: string
                format: uri
              description: URL of the created resource
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'

  /tasks/{taskId}:
    parameters:
      - $ref: '#/components/parameters/TaskIdParam'

    get:
      operationId: getTask
      summary: Get a task by ID
      tags:
        - Tasks
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          $ref: '#/components/responses/NotFound'

    patch:
      operationId: updateTask
      summary: Update a task
      description: Partially updates a task. Only provided fields are updated.
      tags:
        - Tasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateTaskRequest'
      responses:
        '200':
          description: Task updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'

    delete:
      operationId: deleteTask
      summary: Delete a task
      tags:
        - Tasks
      responses:
        '204':
          description: Task deleted successfully
        '404':
          $ref: '#/components/responses/NotFound'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token obtained from /auth/login

  parameters:
    TaskIdParam:
      name: taskId
      in: path
      required: true
      description: Unique task identifier
      schema:
        type: string
        format: uuid
      example: "550e8400-e29b-41d4-a716-446655440000"

    PageParam:
      name: page
      in: query
      description: Page number for pagination (1-indexed)
      schema:
        type: integer
        minimum: 1
        default: 1

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

  schemas:
    Task:
      type: object
      required:
        - id
        - title
        - status
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
          readOnly: true
        title:
          type: string
          minLength: 1
          maxLength: 200
          description: Task title
        description:
          type: string
          maxLength: 5000
          description: Detailed task description (supports Markdown)
        status:
          $ref: '#/components/schemas/TaskStatus'
        priority:
          $ref: '#/components/schemas/Priority'
        project_id:
          type: string
          format: uuid
          description: Associated project ID
        due_date:
          type: string
          format: date
          description: Due date (ISO 8601)
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true

    TaskStatus:
      type: string
      enum:
        - pending
        - in_progress
        - completed
        - cancelled
      description: Current task status
      default: pending

    Priority:
      type: string
      enum:
        - low
        - medium
        - high
        - urgent
      default: medium

    CreateTaskRequest:
      type: object
      required:
        - title
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 5000
        project_id:
          type: string
          format: uuid
        due_date:
          type: string
          format: date
        priority:
          $ref: '#/components/schemas/Priority'

    UpdateTaskRequest:
      type: object
      minProperties: 1
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 5000
        status:
          $ref: '#/components/schemas/TaskStatus'
        priority:
          $ref: '#/components/schemas/Priority'
        due_date:
          type: string
          format: date

    TaskListResponse:
      type: object
      required:
        - data
        - pagination
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Task'
        pagination:
          $ref: '#/components/schemas/Pagination'

    Pagination:
      type: object
      required:
        - page
        - limit
        - total
        - total_pages
      properties:
        page:
          type: integer
        limit:
          type: integer
        total:
          type: integer
        total_pages:
          type: integer
        has_next:
          type: boolean
        has_prev:
          type: boolean

    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable error code
        message:
          type: string
          description: Human-readable error message
        details:
          type: object
          additionalProperties: true
          description: Additional error details

    ValidationError:
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          properties:
            errors:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  message:
                    type: string

  responses:
    BadRequest:
      description: Bad request - invalid parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: "BAD_REQUEST"
            message: "Invalid query parameters"

    Unauthorized:
      description: Authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: "UNAUTHORIZED"
            message: "Invalid or expired token"

    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: "NOT_FOUND"
            message: "Task not found"

    ValidationError:
      description: Validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationError'
          example:
            code: "VALIDATION_ERROR"
            message: "Request validation failed"
            errors:
              - field: "title"
                message: "Title is required"

  examples:
    TaskListExample:
      value:
        data:
          - id: "550e8400-e29b-41d4-a716-446655440000"
            title: "Complete documentation"
            status: "in_progress"
            priority: "high"
            created_at: "2024-01-15T10:30:00Z"
            updated_at: "2024-01-15T10:30:00Z"
        pagination:
          page: 1
          limit: 20
          total: 42
          total_pages: 3
          has_next: true
          has_prev: false

security:
  - bearerAuth: []
多态架构(判别器)
components:
  schemas:
    Notification:
      type: object
      required:
        - id
        - type
        - created_at
      discriminator:
        propertyName: type
        mapping:
          email: '#/components/schemas/EmailNotification'
          sms: '#/components/schemas/SmsNotification'
          push: '#/components/schemas/PushNotification'
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          enum: [email, sms, push]
        created_at:
          type: string
          format: date-time

    EmailNotification:
      allOf:
        - $ref: '#/components/schemas/Notification'
        - type: object
          required:
            - to
            - subject
          properties:
            to:
              type: string
              format: email
            subject:
              type: string
            body:
              type: string

    SmsNotification:
      allOf:
        - $ref: '#/components/schemas/Notification'
        - type: object
          required:
            - phone_number
            - message
          properties:
            phone_number:
              type: string
              pattern: '^\+[1-9]\d{1,14}$'
            message:
              type: string
              maxLength: 160
Spectral lint 规则
# .spectral.yaml
extends: ["spectral:oas"]

rules:
  # Enforce operation IDs
  operation-operationId: error

  # Require descriptions
  operation-description: error
  oas3-schema-description: warn

  # Naming conventions
  path-casing:
    given: "$.paths[*]~"
    then:
      function: casing
      functionOptions:
        type: kebab

  # Security requirements
  operation-security-defined: error

  # Response codes
  operation-success-response: error

  # Custom: require examples
  require-examples:
    message: "Responses should have examples"
    given: "$.paths.*.*.responses.*.content.*.schema"
    then:
      field: example
      function: truthy

最佳实践

  1. 使用组件 - 提取可复用的架构、参数和响应
  2. 提供示例 - 为每个架构提供真实示例
  3. 编写有意义的描述 - 使用 Markdown 格式说明业务背景
  4. 保持命名一致 - 路径使用 kebab-case,属性使用 camelCase
  5. 为 API 设置版本 - 在 URL 或标头中包含版本
  6. 记录错误 - 定义所有错误响应并提供示例
  7. 使用 operationId - 使用唯一且描述清晰的 ID 生成 SDK
  8. 通过 lint 验证 - 使用 Spectral 强制执行标准
  9. 保持规范同步 - 在 CI 中自动执行验证

常见问题

  • 缺少必填字段 - 忘记将字段标记为必填
  • 命名不一致 - 混用 snake_case 和 camelCase
  • 描述过于笼统 - 使用“返回数据”,而不是具体说明
  • 没有示例 - 导致规范难以理解
  • 规范过时 - 规范与实际实现不一致
  • 过度使用 anyOf - 导致架构难以理解
  • 缺少错误响应 - 只记录正常流程
  • 没有分页 - 列表端点未提供分页信息

评论

支持 Markdown