名称: 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配置