mcpField
A
api-designer

api-designer

github.com/404kidwiz开发156 次安装
代码仓库

关于 api-designer

api-designer 是面向 API 设计工作的技能,帮助团队将需求转化为一致且易于理解的 REST 或 GraphQL 接口,涵盖 OpenAPI 3.1、版本策略、分页、HATEOAS 和错误规范。

主要功能

  1. 01REST 与 GraphQL API 架构设计
  2. 02OpenAPI 3.1 规范设计
  3. 03API 版本策略
  4. 04分页、筛选与排序模式
  5. 05HATEOAS 与错误规范化

适用场景

  1. 01根据需求起草 API 设计
  2. 02编写 API 文档规范
  3. 03规划版本与分页策略
  4. 04统一各服务的错误响应

安装

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

$npx skills add https://github.com/404kidwiz/claude-supercode-skills --skill api-designer

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

详细介绍

API 设计师

目的

提供专业的 REST 和 GraphQL API 架构知识,专长于 OpenAPI 3.1 规范、API 版本控制策略、分页模式和超媒体驱动设计(HATEOAS)。专注于构建可扩展、文档完善、方便开发者使用的 API,并确保错误处理得当且遵循标准。

适用场景

  • 根据需求设计 RESTful 或 GraphQL API
  • 创建用于 API 文档的 OpenAPI 3.1 规范
  • 实施 API 版本控制策略(URL、标头、内容协商)
  • 为大型数据集设计分页、筛选和排序模式
  • 构建符合 HATEOAS 标准的 API(超媒体驱动)
  • 在各项服务中统一错误响应和状态码
  • 设计 API 身份验证和授权模式

快速入门

在以下情况调用此技能:

  • 根据需求设计 RESTful 或 GraphQL API
  • 创建用于 API 文档的 OpenAPI 3.1 规范
  • 实施 API 版本控制策略(URL、标头、内容协商)
  • 为大型数据集设计分页、筛选和排序模式
  • 构建符合 HATEOAS 标准的 API(超媒体驱动)
  • 在各项服务中统一错误响应和状态码

以下情况请勿调用:

  • 仅实现已设计好的 API 端点(使用 backend-developer)
  • 不涉及 API 的数据库架构设计(使用 database-administrator)
  • 前端 API 集成(使用 frontend-developer)
  • API 安全实现(身份验证/授权请使用 security-engineer)
  • API 性能优化(使用 performance-engineer)


核心工作流

工作流 1:使用 OpenAPI 3.1 设计 RESTful API

用例: 电商平台需要产品目录 API

步骤 1:资源建模

# Resources identified:
# - Products (CRUD)
# - Categories (read-only, hierarchical)
# - Reviews (nested under products)
# - Inventory (separate resource, linked to products)

# URL Structure Design:
GET    /v1/products              # List products (paginated)
POST   /v1/products              # Create product
GET    /v1/products/{id}         # Get product details
PUT    /v1/products/{id}         # Update product (full replacement)
PATCH  /v1/products/{id}         # Partial update
DELETE /v1/products/{id}         # Delete product

GET    /v1/products/{id}/reviews        # Get reviews for product
POST   /v1/products/{id}/reviews        # Create review
GET    /v1/products/{id}/reviews/{reviewId}  # Get specific review

GET    /v1/categories            # List categories
GET    /v1/categories/{id}       # Get category + subcategories

# Query parameters (filtering, pagination, sorting):
GET /v1/products?category=electronics&min_price=100&max_price=500&sort=price:asc&limit=20&cursor=abc123

步骤 2:OpenAPI 3.1 规范

# openapi.yaml
openapi: 3.1.0
info:
  title: E-commerce Product API
  version: 1.0.0
  description: RESTful API for product catalog management
  contact:
    name: API Support
    email: [email protected]

servers:
  - url: https://api.ecommerce.com/v1
    description: Production server
  - url: https://staging-api.ecommerce.com/v1
    description: Staging server

paths:
  /products:
    get:
      summary: List products
      operationId: listProducts
      tags: [Products]
      parameters:
        - name: category
          in: query
          description: Filter by category slug
          schema:
            type: string
            example: electronics
        - name: min_price
          in: query
          description: Minimum price filter
          schema:
            type: number
            format: float
            minimum: 0
        - name: max_price
          in: query
          description: Maximum price filter
          schema:
            type: number
            format: float
            minimum: 0
        - name: sort
          in: query
          description: Sort order (field:direction)
          schema:
            type: string
            enum: [price:asc, price:desc, created_at:asc, created_at:desc]
            default: created_at:desc
        - name: limit
          in: query
          description: Number of results per page
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: cursor
          in: query
          description: Pagination cursor (opaque token)
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                required: [data, meta, links]
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Product'
                  meta:
                    type: object
                    properties:
                      total_count:
                        type: integer
                        description: Total number of products matching filters
                      has_more:
                        type: boolean
                        description: Whether more results exist
                  links:
                    type: object
                    properties:
                      self:
                        type: string
                        format: uri
                      next:
                        type: string
                        format: uri
                        nullable: true
                      prev:
                        type: string
                        format: uri
                        nullable: true
              examples:
                success:
                  value:
                    data:
                      - id: "prod_123"
                        name: "Wireless Headphones"
                        description: "Premium noise-cancelling headphones"
                        price: 299.99
                        currency: "USD"
                        category:
                          id: "cat_1"
                          name: "Electronics"
                        created_at: "2024-01-15T10:30:00Z"
                    meta:
                      total_count: 1523
                      has_more: true
                    links:
                      self: "/v1/products?limit=20"
                      next: "/v1/products?limit=20&cursor=eyJpZCI6InByb2RfMTIzIn0="
                      prev: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /products/{id}:
    get:
      summary: Get product details
      operationId: getProduct
      tags: [Products]
      parameters:
        - name: id
          in: path
          required: true
          description: Product ID
          schema:
            type: string
            pattern: '^prod_[a-zA-Z0-9]+$'
      responses:
        '200':
          description: Product found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '404':
          $ref: '#/components/responses/NotFound'

components:
  schemas:
    Product:
      type: object
      required: [id, name, price, currency]
      properties:
        id:
          type: string
          description: Unique product identifier
          example: "prod_123"
        name:
          type: string
          minLength: 1
          maxLength: 200
          example: "Wireless Headphones"
        description:
          type: string
          maxLength: 2000
          nullable: true
        price:
          type: number
          format: float
          minimum: 0
          example: 299.99
        currency:
          type: string
          enum: [USD, EUR, GBP, JPY]
          default: USD
        category:
          $ref: '#/components/schemas/Category'
        images:
          type: array
          items:
            type: string
            format: uri
          maxItems: 10
        inventory_count:
          type: integer
          minimum: 0
          description: Available stock
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    Category:
      type: object
      required: [id, name, slug]
      properties:
        id:
          type: string
          example: "cat_1"
        name:
          type: string
          example: "Electronics"
        slug:
          type: string
          pattern: '^[a-z0-9-]+$'
          example: "electronics"
        parent_id:
          type: string
          nullable: true

    Error:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [code, message]
          properties:
            code:
              type: string
              description: Machine-readable error code
              example: "invalid_parameter"
            message:
              type: string
              description: Human-readable error message
              example: "The 'price' parameter must be a positive number"
            details:
              type: object
              description: Additional error context
              additionalProperties: true

  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: "invalid_parameter"
              message: "The 'min_price' parameter must be a non-negative number"
              details:
                parameter: "min_price"
                value: "-10"

    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: "resource_not_found"
              message: "Product with ID 'prod_999' not found"

    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: "internal_server_error"
              message: "An unexpected error occurred. Please try again later."
              details:
                request_id: "req_abc123"

  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

security:
  - ApiKey: []
  - BearerAuth: []

步骤 3:生成文档

# Install Redoc CLI
npm install -g redoc-cli

# Generate static HTML documentation
redoc-cli bundle openapi.yaml -o api-docs.html

# Host documentation
npx serve api-docs.html

# Interactive Swagger UI
docker run -p 8080:8080 -e SWAGGER_JSON=/docs/openapi.yaml \
  -v $(pwd):/docs swaggerapi/swagger-ui

# Open http://localhost:8080 for interactive API testing


反模式与注意事项

❌ 反模式 1:错误响应不一致

表现:

// Endpoint 1: Login failure
{
  "error": "Invalid credentials"
}

// Endpoint 2: Validation failure
{
  "errors": [
    { "field": "email", "message": "Invalid email format" }
  ]
}

// Endpoint 3: Server error
{
  "status": "error",
  "message": "Internal server error",
  "code": 500
}

// Problem: Clients need custom error handling per endpoint

失败原因:

  • 客户端代码变得复杂(需要采用多种错误解析策略)
  • 前端开发者感到困扰(契约不一致)
  • 错误日志记录/监控困难(没有标准格式)

正确做法:

// Standardized error response (all endpoints)
{
  "error": {
    "code": "invalid_credentials",
    "message": "The provided email or password is incorrect",
    "details": null,
    "request_id": "req_abc123"
  }
}

// Validation errors (multiple fields)
{
  "error": {
    "code": "validation_failed",
    "message": "One or more fields failed validation",
    "details": {
      "fields": [
        { "field": "email", "message": "Invalid email format" },
        { "field": "password", "message": "Password must be at least 8 characters" }
      ]
    },
    "request_id": "req_def456"
  }
}

// Client-side error handling (consistent)
function handleApiError(response) {
  const { code, message, details } = response.error;
  
  switch (code) {
    case 'validation_failed':
      // Display field-specific errors
      details.fields.forEach(({ field, message }) => {
        showFieldError(field, message);
      });
      break;
    
    case 'unauthorized':
      // Redirect to login
      redirectToLogin();
      break;
    
    default:
      // Generic error message
      showToast(message);
  }
}


集成模式

backend-developer:

  • 交接:API 设计师创建规范 → 后端实现端点
  • 协作:错误响应格式、身份验证模式
  • 工具:OpenAPI 代码生成、API 模拟

frontend-developer:

  • 交接:发布 API 规范 → 前端使用 API
  • 协作:查询模式、分页、错误处理
  • 工具:根据 OpenAPI/GraphQL 架构生成 TypeScript 类型

security-engineer:

  • 交接:API 设计师定义身份验证需求 → 安全工程师实现身份验证
  • 协作:速率限制、API 密钥管理、OAuth 流程
  • 关键事项:JWT 验证、API 网关安全策略

devops-engineer:

  • 交接:完成 API 设计 → DevOps 部署 API 网关
  • 协作:API 版本控制部署、蓝绿发布
  • 工具:Kong、AWS API Gateway、Traefik 配置

评论

支持 Markdown