mcpField
A
api-design

api-design

github.com/seb1n开发243138 次安装13 周前更新
代码仓库

关于 api-design

api-design 是面向 AI Agent 的技能,用于指导生产级 REST API 设计,涵盖资源建模、端点语义、数据结构和 OpenAPI 文档。它也涉及分页、版本管理和统一错误处理。

主要功能

  1. 01资源及关系建模
  2. 02CRUD 端点与 HTTP 语义
  3. 03请求和响应结构设计
  4. 04分页、筛选与排序
  5. 05版本管理与内容协商
  6. 06OpenAPI 3.0 文档

适用场景

  1. 01根据应用领域设计 API
  2. 02用 OpenAPI 编写端点和结构文档
  3. 03规划列表筛选与分页
  4. 04制定 API 版本和错误规范

安装

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

$npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill api-design

安装后在 Claude Code 中输入/api-design确认已加载。

详细介绍

API 设计

此技能可让 AI Agent 设计达到生产级质量的 RESTful API。Agent 会对资源建模,定义语义正确的端点和 HTTP 方法,选择合适的状态码,实现分页和版本控制策略,并生成 OpenAPI 文档。输出遵循 REST 约束,包括无状态、统一接口和基于资源的 URI。

工作流

  1. 识别资源及其关系: 分析应用领域,提取作为资源的名词(例如,用户、任务、评论)。梳理资源之间的关系——一对多、多对多,并确定适合采用子资源还是独立集合。避免基于动词的端点;资源应代表实体,而非操作。

  2. 定义端点和 HTTP 方法: 为每个资源使用正确的 HTTP 方法定义 CRUD 端点。使用 GET 获取资源(安全、幂等),使用 POST 创建资源(非幂等),使用 PUT 完整替换资源(幂等),使用 PATCH 部分更新资源(幂等),使用 DELETE 删除资源(幂等)。当关系紧密时,将子资源嵌套在其父资源下(例如,/tasks/{id}/comments)。

  3. 设计请求和响应架构: 为每个端点定义 JSON 请求正文、响应载荷和查询参数。统一使用 snake_case 或 camelCase 字段名。指定必填字段和可选字段、数据类型及验证约束。设计一套适用于所有端点的一致错误响应封装。

  4. 实现分页、筛选和排序: 为列表端点添加基于游标或偏移量的分页,并使用 limit 和 offset(或 cursor)查询参数。通过查询参数支持筛选(例如,?status=active),并使用 sort 和 order 参数进行排序。在响应正文中返回分页元数据,包括总数以及下一页/上一页链接。

  5. 定义版本控制和内容协商: 选择一种版本控制策略——URI 路径(/v1/tasks)、查询参数(?version=1)或 Accept 标头(Accept: application/vnd.api.v1+json)。URI 路径版本控制最简单,也最常见。确保同一版本内向后兼容,并记录弃用时间表。

  6. 生成 OpenAPI 文档: 生成完整的 OpenAPI 3.0 规范,包含路径、架构、安全方案以及请求/响应示例。在响应文档中包含速率限制标头(X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset)。

支持的技术

  • 规范格式: OpenAPI 3.0/3.1、JSON Schema、AsyncAPI(用于事件驱动扩展)
  • 框架: Express.js、FastAPI、Django REST Framework、Spring Boot、Rails API
  • 文档工具: Swagger UI、Redoc、Stoplight
  • 测试: Postman、Insomnia、REST Client(VS Code)、curl

用法

向 Agent 提供应用领域的描述、涉及的实体以及用户需要执行的操作。Agent 将生成端点定义、请求/响应架构和 OpenAPI 规范。你可以通过请求修改特定端点、添加分页或调整错误格式来迭代完善。

示例

示例 1:任务管理 API(OpenAPI 规范片段)
openapi: 3.0.3
info:
  title: Task Management API
  version: 1.0.0
  description: RESTful API for managing tasks and projects.

servers:
  - url: https://api.example.com/v1

paths:
  /tasks:
    get:
      summary: List all tasks
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [pending, in_progress, done]
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Paginated list of tasks
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
            X-RateLimit-Remaining:
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Task"
                  pagination:
                    $ref: "#/components/schemas/CursorPagination"
    post:
      summary: Create a new task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaskCreate"
      responses:
        "201":
          description: Task created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /tasks/{taskId}:
    get:
      summary: Get a task by ID
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Task details
        "404":
          description: Task not found

components:
  schemas:
    Task:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum: [pending, in_progress, done]
        created_at:
          type: string
          format: date-time
    TaskCreate:
      type: object
      required: [title]
      properties:
        title:
          type: string
          maxLength: 255
        description:
          type: string
        assignee_id:
          type: string
          format: uuid
    CursorPagination:
      type: object
      properties:
        next_cursor:
          type: string
          nullable: true
        has_more:
          type: boolean
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  reason:
                    type: string
示例 2:一致的错误响应格式
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed.",
    "details": [
      {
        "field": "title",
        "reason": "Title is required and cannot be empty."
      },
      {
        "field": "assignee_id",
        "reason": "Must be a valid UUID."
      }
    ],
    "request_id": "req_abc123",
    "documentation_url": "https://api.example.com/docs/errors#VALIDATION_ERROR"
  }
}

所有端点应统一使用以下标准错误代码:

HTTP 状态错误代码含义
400BAD_REQUEST请求语法格式错误
401UNAUTHORIZED缺少身份验证或身份验证无效
403FORBIDDEN已通过身份验证,但权限不足
404NOT_FOUND资源不存在
409CONFLICT资源状态冲突(例如,重复)
422VALIDATION_ERROR语义验证失败
429RATE_LIMITED请求过多
500INTERNAL_ERROR意外的服务端错误

最佳实践

  • 资源路径使用复数名词(/tasks,而非 /task),并避免在 URI 中使用动词。无法映射到 CRUD 的操作应使用子资源(例如,POST /tasks/{id}/archive)。
  • 通过支持 POST 请求中的 Idempotency-Key 标头来实现幂等性。PUT 和 DELETE 天然具有幂等性;应清楚说明这一行为。
  • 在每个响应中包含限流标头(X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset),以便客户端自行控制请求速率。
  • 在响应中使用 HATEOAS 链接,以便发现 API。适当时,包含 _links,其中提供 self、next、prev 和相关资源 URI。
  • 从第一天起就进行版本控制,即使目前只有 v1。这样可以避免日后进行痛苦的迁移。弃用旧版本时,应使用 Sunset 和 Deprecation 标头。
  • 在 201 Created 响应中返回 Location 标头,指向新创建的资源 URI。

边缘情况

  • 空集合: 返回 200 OK,并附带空的 data 数组和 has_more: false,而不是 404。
  • 已删除的资源: 对于硬删除的资源,返回 404 Not Found。对于软删除的资源,返回 410 Gone,并附带资源删除时间的元数据。
  • 并发更新: 使用 ETag 和 If-Match 标头进行乐观并发控制。如果资源自客户端上次获取后已发生变化,则返回 412 Precondition Failed。
  • 批量操作中的部分失败: 返回 207 Multi-Status,并附带每项的状态码,以便客户端了解哪些项目成功、哪些失败。
  • 尾部斜杠: 将 /tasks/ 和 /tasks 规范化为由同一个处理程序处理。如果强制使用一种规范形式,则返回 301 重定向。
  • 未知查询参数: 静默忽略未知参数,或返回带有明确说明的 400——选择一种策略并保持一致。

评论

支持 Markdown