api-designer

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

API Designer

API设计师

Purpose

用途

Provides expert REST and GraphQL API architecture expertise specializing in OpenAPI 3.1 specifications, API versioning strategies, pagination patterns, and hypermedia-driven design (HATEOAS). Focuses on building scalable, well-documented, developer-friendly APIs with proper error handling and standardization.
提供专业的REST和GraphQL API架构专业知识,专注于OpenAPI 3.1规范、API版本控制策略、分页模式和超媒体驱动设计(HATEOAS)。重点是构建具有适当错误处理和标准化的可扩展、文档完善、对开发者友好的API。

When to Use

使用场景

  • Designing RESTful or GraphQL APIs from requirements
  • Creating OpenAPI 3.1 specifications for API documentation
  • Implementing API versioning strategies (URL, header, content negotiation)
  • Designing pagination, filtering, and sorting patterns for large datasets
  • Building HATEOAS-compliant APIs (hypermedia-driven)
  • Standardizing error responses and status codes across services
  • Designing API authentication and authorization patterns
  • 根据需求设计RESTful或GraphQL API
  • 为API文档创建OpenAPI 3.1规范
  • 实现API版本控制策略(URL、请求头、内容协商)
  • 为大型数据集设计分页、过滤和排序模式
  • 构建符合HATEOAS规范的API(超媒体驱动)
  • 跨服务标准化错误响应和状态码
  • 设计API认证与授权模式

Quick Start

快速入门

Invoke this skill when:
  • Designing RESTful or GraphQL APIs from requirements
  • Creating OpenAPI 3.1 specifications for API documentation
  • Implementing API versioning strategies (URL, header, content negotiation)
  • Designing pagination, filtering, and sorting patterns for large datasets
  • Building HATEOAS-compliant APIs (hypermedia-driven)
  • Standardizing error responses and status codes across services
Do NOT invoke when:
  • Only implementing pre-designed API endpoints (use backend-developer)
  • Database schema design without API context (use database-administrator)
  • Frontend API integration (use frontend-developer)
  • API security implementation (use security-engineer for authentication/authorization)
  • API performance optimization (use performance-engineer)


在以下场景调用此技能:
  • 根据需求设计RESTful或GraphQL API
  • 为API文档创建OpenAPI 3.1规范
  • 实现API版本控制策略(URL、请求头、内容协商)
  • 为大型数据集设计分页、过滤和排序模式
  • 构建符合HATEOAS规范的API(超媒体驱动)
  • 跨服务标准化错误响应和状态码
请勿在以下场景调用:
  • 仅实现预先设计好的API端点(请使用backend-developer)
  • 脱离API上下文的数据库 schema 设计(请使用database-administrator)
  • 前端API集成(请使用frontend-developer)
  • API安全实现(认证/授权请使用security-engineer)
  • API性能优化(请使用performance-engineer)


Core Workflows

核心工作流

Workflow 1: Design RESTful API with OpenAPI 3.1

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

Use case: E-commerce platform needs product catalog API
Step 1: Resource Modeling
yaml
undefined
用例: 电商平台需要商品目录API
步骤1:资源建模
yaml
undefined

Resources identified:

Resources identified:

- Products (CRUD)

- Products (CRUD)

- Categories (read-only, hierarchical)

- Categories (read-only, hierarchical)

- Reviews (nested under products)

- Reviews (nested under products)

- Inventory (separate resource, linked to products)

- Inventory (separate resource, linked to products)

URL Structure Design:

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
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):

Query parameters (filtering, pagination, sorting):

GET /v1/products?category=electronics&min_price=100&max_price=500&sort=price:asc&limit=20&cursor=abc123

**Step 2: OpenAPI 3.1 Specification**
```yaml
GET /v1/products?category=electronics&min_price=100&max_price=500&sort=price:asc&limit=20&cursor=abc123

**步骤2:OpenAPI 3.1规范**
```yaml

openapi.yaml

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: api@ecommerce.com
servers:
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: []

**Step 3: Generate Documentation**
```bash
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: api@ecommerce.com
servers:
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:生成文档**
```bash

Install Redoc CLI

Install Redoc CLI

npm install -g redoc-cli
npm install -g redoc-cli

Generate static HTML documentation

Generate static HTML documentation

redoc-cli bundle openapi.yaml -o api-docs.html
redoc-cli bundle openapi.yaml -o api-docs.html

Host documentation

Host documentation

npx serve api-docs.html
npx serve api-docs.html

Interactive Swagger UI

Interactive Swagger UI

docker run -p 8080:8080 -e SWAGGER_JSON=/docs/openapi.yaml
-v $(pwd):/docs swaggerapi/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

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


---
---

---
---

Anti-Patterns & Gotchas

反模式与注意事项

❌ Anti-Pattern 1: Inconsistent Error Responses

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

What it looks like:
json
// 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
Why it fails:
  • Client code becomes complex (multiple error parsing strategies)
  • Frontend developers frustrated (inconsistent contracts)
  • Error logging/monitoring difficult (no standard format)
Correct approach:
json
// 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);
  }
}


表现:
json
// 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
问题所在:
  • 客户端代码变得复杂(多种错误解析策略)
  • 前端开发者受挫(不一致的契约)
  • 错误日志/监控困难(无标准格式)
正确做法:
json
// 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);
  }
}


Integration Patterns

集成模式

backend-developer:
  • Handoff: API designer creates spec → Backend implements endpoints
  • Collaboration: Error response formats, authentication patterns
  • Tools: OpenAPI code generation, API mocking
frontend-developer:
  • Handoff: API spec published → Frontend consumes API
  • Collaboration: Query patterns, pagination, error handling
  • Tools: TypeScript type generation from OpenAPI/GraphQL schema
security-engineer:
  • Handoff: API designer defines authentication needs → Security implements auth
  • Collaboration: Rate limiting, API key management, OAuth flows
  • Critical: JWT validation, API gateway security policies
devops-engineer:
  • Handoff: API design finalized → DevOps deploys API gateway
  • Collaboration: API versioning deployment, blue-green releases
  • Tools: Kong, AWS API Gateway, Traefik configuration

backend-developer:
  • 交接:API设计师创建规范 → 后端实现端点
  • 协作:错误响应格式、认证模式
  • 工具:OpenAPI代码生成、API模拟
frontend-developer:
  • 交接:API规范发布 → 前端调用API
  • 协作:查询模式、分页、错误处理
  • 工具:从OpenAPI/GraphQL schema生成TypeScript类型
security-engineer:
  • 交接:API设计师定义认证需求 → 安全团队实现认证
  • 协作:速率限制、API密钥管理、OAuth流程
  • 关键:JWT验证、API网关安全策略
devops-engineer:
  • 交接:API设计定稿 → DevOps部署API网关
  • 协作:API版本控制部署、蓝绿发布
  • 工具:Kong、AWS API Gateway、Traefik配置