API设计师Skill api-designer

API设计师是专业的REST和GraphQL API架构专家,专注于OpenAPI 3.1规范、HATEOAS超媒体驱动设计、API版本控制策略、分页模式、错误响应标准化和认证授权模式设计。提供可扩展、文档完善、开发者友好的API设计解决方案,适用于电子商务、微服务架构、企业级应用等场景。关键词:API设计、OpenAPI 3.1、RESTful API、GraphQL、HATEOAS、API版本控制、分页策略、错误处理标准化、API文档生成、微服务架构设计。

后端开发 0 次安装 6 次浏览 更新于 2/23/2026

名称: API设计师 描述: REST/GraphQL API架构专家,专注于OpenAPI 3.1规范、HATEOAS、分页和版本控制策略

API设计师

目的

提供专业的REST和GraphQL API架构专业知识,专注于OpenAPI 3.1规范、API版本控制策略、分页模式和超媒体驱动设计(HATEOAS)。专注于构建可扩展、文档完善、开发者友好的API,具备适当的错误处理和标准化。

使用时机

  • 根据需求设计RESTful或GraphQL API
  • 创建OpenAPI 3.1规范用于API文档
  • 实施API版本控制策略(URL、头部、内容协商)
  • 设计大数据集的分页、过滤和排序模式
  • 构建符合HATEOAS的API(超媒体驱动)
  • 跨服务标准化错误响应和状态码
  • 设计API认证和授权模式

快速开始

在以下情况下调用此技能:

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

不要在以下情况下调用:

  • 仅实现预设计的API端点(使用后端开发人员)
  • 没有API上下文的数据库模式设计(使用数据库管理员)
  • 前端API集成(使用前端开发人员)
  • API安全实现(使用安全工程师进行认证/授权)
  • API性能优化(使用性能工程师)


核心工作流程

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

使用案例: 电子商务平台需要产品目录API

步骤1:资源建模

# 识别的资源:
# - 产品(CRUD)
# - 分类(只读,分层)
# - 评论(嵌套在产品下)
# - 库存(独立资源,链接到产品)

# URL结构设计:
GET    /v1/products              # 列出产品(分页)
POST   /v1/products              # 创建产品
GET    /v1/products/{id}         # 获取产品详情
PUT    /v1/products/{id}         # 更新产品(完全替换)
PATCH  /v1/products/{id}         # 部分更新
DELETE /v1/products/{id}         # 删除产品

GET    /v1/products/{id}/reviews        # 获取产品评论
POST   /v1/products/{id}/reviews        # 创建评论
GET    /v1/products/{id}/reviews/{reviewId}  # 获取特定评论

GET    /v1/categories            # 列出分类
GET    /v1/categories/{id}       # 获取分类 + 子分类

# 查询参数(过滤、分页、排序):
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: 电子商务产品API
  version: 1.0.0
  description: 用于产品目录管理的RESTful API
  contact:
    name: API支持
    email: api@ecommerce.com

servers:
  - url: https://api.ecommerce.com/v1
    description: 生产服务器
  - url: https://staging-api.ecommerce.com/v1
    description: 测试服务器

paths:
  /products:
    get:
      summary: 列出产品
      operationId: listProducts
      tags: [产品]
      parameters:
        - name: category
          in: query
          description: 按分类slug过滤
          schema:
            type: string
            example: electronics
        - name: min_price
          in: query
          description: 最低价格过滤器
          schema:
            type: number
            format: float
            minimum: 0
        - name: max_price
          in: query
          description: 最高价格过滤器
          schema:
            type: number
            format: float
            minimum: 0
        - name: sort
          in: query
          description: 排序顺序(字段:方向)
          schema:
            type: string
            enum: [price:asc, price:desc, created_at:asc, created_at:desc]
            default: created_at:desc
        - name: limit
          in: query
          description: 每页结果数量
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: cursor
          in: query
          description: 分页游标(不透明令牌)
          schema:
            type: string
      responses:
        '200':
          description: 成功响应
          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: 匹配过滤器的产品总数
                      has_more:
                        type: boolean
                        description: 是否存在更多结果
                  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: "无线耳机"
                        description: "高级降噪耳机"
                        price: 299.99
                        currency: "USD"
                        category:
                          id: "cat_1"
                          name: "电子产品"
                        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: 获取产品详情
      operationId: getProduct
      tags: [产品]
      parameters:
        - name: id
          in: path
          required: true
          description: 产品ID
          schema:
            type: string
            pattern: '^prod_[a-zA-Z0-9]+$'
      responses:
        '200':
          description: 找到产品
          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: 唯一产品标识符
          example: "prod_123"
        name:
          type: string
          minLength: 1
          maxLength: 200
          example: "无线耳机"
        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: 可用库存
        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: "电子产品"
        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: 机器可读错误代码
              example: "invalid_parameter"
            message:
              type: string
              description: 人类可读错误消息
              example: "'price'参数必须是正数"
            details:
              type: object
              description: 额外错误上下文
              additionalProperties: true

  responses:
    BadRequest:
      description: 无效请求参数
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: "invalid_parameter"
              message: "'min_price'参数必须是非负数"
              details:
                parameter: "min_price"
                value: "-10"

    NotFound:
      description: 资源未找到
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: "resource_not_found"
              message: "ID为'prod_999'的产品未找到"

    InternalServerError:
      description: 内部服务器错误
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: "internal_server_error"
              message: "发生意外错误。请稍后重试。"
              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:生成文档

# 安装Redoc CLI
npm install -g redoc-cli

# 生成静态HTML文档
redoc-cli bundle openapi.yaml -o api-docs.html

# 托管文档
npx serve api-docs.html

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

# 打开 http://localhost:8080 进行交互式API测试


反模式与陷阱

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

表现:

// 端点1:登录失败
{
  "error": "无效凭据"
}

// 端点2:验证失败
{
  "errors": [
    { "field": "email", "message": "无效的电子邮件格式" }
  ]
}

// 端点3:服务器错误
{
  "status": "error",
  "message": "内部服务器错误",
  "code": 500
}

// 问题:客户端需要为每个端点定制错误处理

失败原因:

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

正确方法:

// 标准化错误响应(所有端点)
{
  "error": {
    "code": "invalid_credentials",
    "message": "提供的电子邮件或密码不正确",
    "details": null,
    "request_id": "req_abc123"
  }
}

// 验证错误(多个字段)
{
  "error": {
    "code": "validation_failed",
    "message": "一个或多个字段验证失败",
    "details": {
      "fields": [
        { "field": "email", "message": "无效的电子邮件格式" },
        { "field": "password", "message": "密码必须至少8个字符" }
      ]
    },
    "request_id": "req_def456"
  }
}

// 客户端错误处理(一致)
function handleApiError(response) {
  const { code, message, details } = response.error;
  
  switch (code) {
    case 'validation_failed':
      // 显示字段特定错误
      details.fields.forEach(({ field, message }) => {
        showFieldError(field, message);
      });
      break;
    
    case 'unauthorized':
      // 重定向到登录
      redirectToLogin();
      break;
    
    default:
      // 通用错误消息
      showToast(message);
  }
}


集成模式

后端开发人员:

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

前端开发人员:

  • 交接:API规范发布 → 前端消费API
  • 协作:查询模式、分页、错误处理
  • 工具:从OpenAPI/GraphQL模式生成TypeScript类型

安全工程师:

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

DevOps工程师:

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