API Architect — Full Lifecycle API Development
设计、构建、测试、文档编制、安全保障和监控生产级API。不仅仅是curl命令 —— 一套完整的工程方法论。
何时使用
- 设计新API(REST、GraphQL或gRPC)
- 审核现有API的质量、一致性或安全性
- 生成或验证OpenAPI/Swagger规范
- 构建全面的测试套件(单元、集成、契约、负载)
- 调试生产API问题
- 规划API版本控制和弃用
- 设置监控、速率限制和错误处理
第一阶段:API设计
设计先行方法
总是在编码前进行设计。规范即是合同。
资源建模
使用此模板将您的领域映射到资源:
# api-design.yaml
service: order-management
base_path: /api/v1
resources:
- name: orders
path: /orders
description: 客户购买订单
identifier: order_id (UUID)
parent: null
operations: [list, create, get, update, cancel]
sub_resources:
- name: line_items
path: /orders/{order_id}/items
operations: [list, add, update, remove]
- name: payments
path: /orders/{order_id}/payments
operations: [list, create, get, refund]
states: [draft, confirmed, processing, shipped, delivered, cancelled]
transitions:
- from: draft → to: confirmed (action: confirm)
- from: confirmed → to: processing (action: process)
- from: processing → to: shipped (action: ship)
- from: shipped → to: delivered (action: deliver)
- from: [draft, confirmed] → to: cancelled (action: cancel)
命名约定检查表
| 规则 | 好的 | 坏的 |
|---|---|---|
| 集合使用复数名词 | /users |
/user, /getUsers |
| 多词使用小破折号 | /line-items |
/lineItems, /line_items |
| URL中无动词 | POST /orders |
/createOrder |
| 嵌套表示所有权 | /users/123/orders |
/orders?user=123(对于主要关系) |
| 最多3级深度 | /users/123/orders |
/users/123/orders/456/items/789/options |
| 通过查询参数过滤 | /orders?status=active |
/active-orders |
| 操作作为子资源 | POST /orders/123/cancel |
PATCH /orders/123 {cancelled:true} |
HTTP方法 —— 决策矩阵
需要... → 方法 幂等? 安全?
获取资源或集合 → GET 是 是
创建新资源 → POST 否 否
完全替换资源 → PUT 是 否
部分更新资源 → PATCH 否* 否
移除资源 → DELETE 是 否
检查资源是否存在 → HEAD 是 是
列出允许的方法 → OPTIONS 是 是
* PATCH可以是幂等的,如果使用JSON Merge Patch
状态码决策树
成功?
├── 创建了新内容? → 201 Created(Location头部)
├── 接受异步处理? → 202 Accepted(包括状态URL)
├── 没有返回体? → 204 No Content
└── 返回数据? → 200 OK
客户端错误?
├── 请求语法错误? → 400 Bad Request
├── 没有/无效凭证? → 401 Unauthorized
├── 有效凭证但权限不足? → 403 Forbidden
├── 资源不存在? → 404 Not Found
├── 方法不允许在资源上? → 405 Method Not Allowed
├── 与当前状态冲突? → 409 Conflict
├── 资源永久消失? → 410 Gone
├── 验证失败? → 422 Unprocessable Entity
├── 请求太多? → 429 Too Many Requests(Retry-After头部)
└── 先决条件失败(etag不匹配)? → 412 Precondition Failed
服务器错误?
├── 意外失败? → 500 Internal Server Error
├── 上游依赖失败? → 502 Bad Gateway
├── 临时过载? → 503 Service Unavailable(Retry-After)
└── 上游超时? → 504 Gateway Timeout
请求/响应设计
标准响应信封
// 成功(单个资源)
{
"data": { "id": "ord_abc123", "status": "confirmed", ... },
"meta": { "request_id": "req_xyz789" }
}
// 成功(集合)
{
"data": [ ... ],
"meta": { "request_id": "req_xyz789" },
"pagination": {
"total": 142,
"page": 2,
"per_page": 20,
"total_pages": 8,
"next": "/api/v1/orders?page=3&per_page=20",
"prev": "/api/v1/orders?page=1&per_page=20"
}
}
// 错误
{
"error": {
"code": "VALIDATION_FAILED",
"message": "请求验证失败",
"details": [
{ "field": "email", "message": "必须是有效的电子邮件地址", "code": "INVALID_FORMAT" },
{ "field": "age", "message": "必须至少18岁", "code": "MIN_VALUE", "min": 18 }
]
},
"meta": { "request_id": "req_xyz789" }
}
分页模式 —— 使用哪种
| 模式 | 使用时 | 优点 | 缺点 |
|---|---|---|---|
Offset ?page=2&per_page=20 |
简单的UI分页,小数据集 | 易于实现,页面跳转 | 插入时漂移,大偏移时慢 |
Cursor ?after=eyJ...&limit=20 |
无限滚动,实时馈送,大数据集 | 一致的,性能好 | 没有页面跳转,不透明的游标 |
Keyset ?created_after=2024-01-01&limit=20 |
时间序列数据,日志 | 快速,透明 | 需要可排序字段,没有计数 |
过滤、排序、字段选择
# 过滤
GET /orders?status=active&created_after=2024-01-01&total_min=100
# 排序(前缀-表示降序)
GET /orders?sort=-created_at,total
# 字段选择(减少负载)
GET /orders?fields=id,status,total,customer.name
# 搜索
GET /products?q=wireless+headphones
# 组合
GET /orders?status=active&sort=-created_at&fields=id,status,total&page=1&per_page=10
第二阶段:OpenAPI规范
生成OpenAPI 3.1规范
为您设计的每个资源生成完整的规范:
openapi: 3.1.0
info:
title: Order Management API
version: 1.0.0
description: |
订单生命周期管理。
## 认证
所有端点都需要Bearer令牌认证。
## 速率限制
- 标准:每分钟100个请求
- 批量操作:每分钟10个请求
contact:
name: API Support
email: api@example.com
license:
name: MIT
servers:
- url: https://api.example.com/v1
description: 生产
- url: https://staging-api.example.com/v1
description: 暂存
paths:
/orders:
get:
operationId: listOrders
summary: 列出订单
tags: [Orders]
parameters:
- $ref: '#/components/parameters/PageParam'
- $ref: '#/components/parameters/PerPageParam'
- name: status
in: query
schema:
$ref: '#/components/schemas/OrderStatus'
- name: created_after
in: query
schema:
type: string
format: date-time
responses:
'200':
description: 订单列表
content:
application/json:
schema:
$ref: '#/components/schemas/OrderListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createOrder
summary: 创建订单
tags: [Orders]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrderRequest'
examples:
basic:
summary: 基本订单
value:
customer_id: "cust_abc"
items:
- product_id: "prod_xyz"
quantity: 2
responses:
'201':
description: 订单已创建
headers:
Location:
schema:
type: string
description: 创建的订单URL
content:
application/json:
schema:
$ref: '#/components/schemas/OrderResponse'
'422':
$ref: '#/components/responses/ValidationError'
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
parameters:
PageParam:
name: page
in: query
schema: { type: integer, minimum: 1, default: 1 }
PerPageParam:
name: per_page
in: query
schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
responses:
Unauthorized:
description: 缺少或无效的认证
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
ValidationError:
description: 请求验证失败
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
security:
- BearerAuth: []
规范质量检查表(每项0-2分)
| # | 检查 | 分数 |
|---|---|---|
| 1 | 每个端点都有operationId | /2 |
| 2 | 所有参数都有类型+约束文档 | /2 |
| 3 | 请求体有示例 | /2 |
| 4 | 所有错误响应都有文档(400, 401, 403, 404, 422, 429, 500) | /2 |
| 5 | 共享模式使用$ref(DRY) | /2 |
| 6 | 分页参数标准化 | /2 |
| 7 | 安全方案定义+全局应用 | /2 |
| 8 | 描述包括认证、速率限制、版本控制信息 | /2 |
| 9 | 响应头部文档(Location, Retry-After, ETag) | /2 |
| 10 | 枚举用于固定值集 | /2 |
分数: ___/20(目标:16+)
第三阶段:实现模式
请求验证层
每个端点在处理前必须验证:
验证顺序:
1. Content-Type头部(非JSON早期拒绝)
2. 认证(401前不要浪费周期)
3. 授权(403 - 此用户是否有访问权限?)
4. 路径参数(404 - 资源是否存在?)
5. 查询参数(400 - 有效类型/范围?)
6. 请求体模式(422 - 结构是否有效?)
7. 商业规则(422 - 有效的状态转换?)
错误处理 —— 标准错误代码
为您的API定义一致的错误代码枚举:
# 认证 & 授权
AUTH_REQUIRED —— 未提供凭证
AUTH_INVALID —— 凭证无效/过期
AUTH_INSUFFICIENT —— 凭证有效,权限错误
AUTH_RATE_LIMITED —— 认证尝试太多
# 验证
VALIDATION_FAILED —— 通用验证错误(见详情数组)
INVALID_FORMAT —— 字段格式错误(电子邮件、UUID等)
REQUIRED_FIELD —— 必填字段缺失
OUT_OF_RANGE —— 值超出允许范围
INVALID_ENUM —— 值不在允许的集合中
# 资源
NOT_FOUND —— 资源不存在
ALREADY_EXISTS —— 重复(唯一约束)
CONFLICT —— 状态冲突(例如,已取消)
GONE —— 资源永久删除
# 商业逻辑
INSUFFICIENT_FUNDS —— 与支付相关的
QUOTA_EXCEEDED —— 使用限制达到
FEATURE_DISABLED —— 功能标志关闭
DEPENDENCY_FAILED —— 上游服务错误
# 系统
INTERNAL_ERROR —— 意外的服务器错误
SERVICE_UNAVAILABLE —— 暂时关闭
TIMEOUT —— 请求耗时太长
幂等性
对于非幂等操作(POST),需要一个幂等密钥:
请求:
POST /orders
Idempotency-Key: ord_req_abc123
服务器行为:
1. 检查是否之前见过Idempotency-Key
2. 如果是 → 返回缓存的响应(相同的状态,相同的体)
3. 如果不是 → 处理请求,缓存响应24小时
4. 密钥格式:客户端生成的UUID或有意义的字符串
速率限制
要包括的标准头部:
X-RateLimit-Limit: 100 # 每个窗口的最大请求数
X-RateLimit-Remaining: 67 # 当前窗口中剩余的
X-RateLimit-Reset: 1706886400 # 窗口重置时的Unix时间戳
Retry-After: 30 # 等待秒数(429时)
速率限制等级:
| 等级 | 限制 | 窗口 | 使用案例 |
|---|---|---|---|
| 标准 | 100/min | 滑动 | 正常API调用 |
| 批量 | 10/min | 滑动 | 批量操作 |
| 搜索 | 30/min | 滑动 | 全文搜索 |
| 认证 | 5/min | 固定 | 登录尝试 |
| Webhook | 1000/min | 滑动 | 传入Webhook |
第四阶段:测试策略
API测试金字塔
/ E2E \ — 5-10个关键用户流程
/ 契约 \ — 模式验证,向后兼容
/ 集成 \ — 数据库,外部服务,认证
/ 单元测试 \ — 商业逻辑,验证,转换
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
每个端点的测试清单
对于每个端点,测试这些场景:
endpoint: POST /orders
tests:
happy_path:
- 使用有效数据创建订单 → 201
- 返回创建的资源ID
- Location头部指向新资源
- 时间戳设置(created_at, updated_at)
validation:
- 缺少必填字段 → 422带字段级错误
- 无效字段类型(预期为整数的字符串) → 422
- 空体 → 400
- 无效Content-Type → 415
- 额外未知字段 → 忽略或422(选择一个,保持一致)
- 边界值(最小/最大长度,0,负数,空字符串与null)
authentication:
- 无令牌 → 401
- 过期令牌 → 401
- 无效令牌 → 401
- 有效令牌,错误范围 → 403
authorization:
- 用户访问自己的资源 → 200
- 用户访问他人的资源 → 403或404(安全选择)
- 管理员访问任何资源 → 200
edge_cases:
- 重复创建(相同的幂等密钥) → 相同的201响应
- 并发创建竞争条件 → 一个成功,一个得到409
- 资源达到最大关系 → 422
- 文本字段中的Unicode → 正确处理
- 非常长的字符串 → 422带最大长度错误
- 参数中的SQL注入 → 无效果(参数化查询)
- 文本字段中的XSS → 安全存储,输出时转义
performance:
- 响应时间 < 200ms(p95)
- 列出10K记录的端点 → 分页的,< 500ms
- 批量操作超时处理
curl测试配方
# === 设置 ===
BASE="https://api.example.com/v1"
TOKEN="your_bearer_token"
alias api='curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json"'
# === CRUD生命周期测试 ===
# 创建
ORDER=$(api -X POST "$BASE/orders" -d '{"customer_id":"cust_1","items":[{"product_id":"prod_1","qty":2}]}')
ORDER_ID=$(echo "$ORDER" | jq -r '.data.id')
echo "Created: $ORDER_ID"
# 读取
api "$BASE/orders/$ORDER_ID" | jq .
# 更新
api -X PATCH "$BASE/orders/$ORDER_ID" -d '{"notes":"Rush order"}' | jq .
# 带过滤器的列表
api "$BASE/orders?status=draft&sort=-created_at&per_page=5" | jq .
# 操作(状态转换)
api -X POST "$BASE/orders/$ORDER_ID/confirm" | jq .
# 删除
curl -s -o /dev/null -w "%{http_code}" -X DELETE -H "Authorization: Bearer $TOKEN" "$BASE/orders/$ORDER_ID"
# === 错误测试 ===
# 无认证
curl -s "$BASE/orders" | jq .error
# 无效体
api -X POST "$BASE/orders" -d '{"invalid": true}' | jq .error
# 未找到
api "$BASE/orders/nonexistent" | jq .error
# === 性能 ===
# 时间分解
curl -s -o /dev/null -w "DNS:%{time_namelookup} TCP:%{time_connect} TLS:%{time_appconnect} TTFB:%{time_starttransfer} Total:%{time_total}
" -H "Authorization: Bearer $TOKEN" "$BASE/orders"
# 快速负载测试(50个请求,10个并发)
seq 50 | xargs -P10 -I{} curl -s -o /dev/null -w "%{http_code} %{time_total}s
" -H "Authorization: Bearer $TOKEN" "$BASE/orders"
契约测试
验证您的API没有破坏向后兼容性:
# contract-tests.yaml
contract:
name: Order API Contract
version: 1.0.0
rules:
# 这些更改是安全的(非破坏性)
safe:
- 在响应中添加新的可选字段
- 添加新端点
- 添加新的可选查询参数
- 添加新的枚举值(如果客户端处理未知)
- 放宽约束(min: 5 → min: 1)
# 这些更改是破坏性的
breaking:
- 删除响应字段
- 重命名响应字段
- 更改字段类型
- 添加新的必需请求字段
- 删除端点
- 缩小约束(max: 100 → max: 50)
- 更改错误响应格式
- 删除枚举值
# 每次更改后验证
checks:
- 所有现有字段仍然出现在响应中
- 所有现有字段类型未更改
- 所有现有必需字段仍然必需(不多,不少)
- 默认值未更改
- 错误格式未更改
第五阶段:安全
安全检查表(审核每个API)
authentication:
- [ ] 所有端点都需要认证(除了/health, /docs, 公共Webhooks)
- [ ] 令牌过期(短期访问+长期刷新)
- [ ] 支持令牌轮换
- [ ] 认证失败返回401,不泄露信息
- [ ] API密钥存储时是哈希的(绝不要明文)
authorization:
- [ ] 资源级检查(用户只能访问自己的数据)
- [ ] 端点级检查(基于角色的访问)
- [ ] 没有IDOR漏洞(不能猜测其他用户的资源ID)
- [ ] 管理员端点单独保护
- [ ] Webhook端点验证签名
input_validation:
- [ ] 所有输入在服务器端验证(永远不要信任客户端)
- [ ] 防止SQL注入(仅限参数化查询)
- [ ] 防止NoSQL注入
- [ ] 防止路径遍历
- [ ] 请求大小限制(体、头部、URL长度)
- [ ] 文件上传类型限制并扫描
output_security:
- [ ] 响应中无敏感数据(密码、令牌、内部ID)
- [ ] 生产错误中无堆栈跟踪
- [ ] 一致的错误格式(不同错误类型中无信息泄露)
- [ ] 日志中PII脱敏
transport:
- [ ] 仅HTTPS(HTTP重定向到HTTPS)
- [ ] 设置HSTS头部
- [ ] 需要TLS 1.2+
- [ ] CORS配置限制性(特定来源,不是*)
headers:
- [ ] X-Content-Type-Options: nosniff
- [ ] X-Frame-Options: DENY
- [ ] 设置内容安全策略
- [ ] 无服务器版本头部
- [ ] 敏感端点的Cache-Control: no-store
CORS配置
# 限制性(推荐)
cors:
origins:
- https://app.example.com
- https://admin.example.com
methods: [GET, POST, PUT, PATCH, DELETE]
headers: [Authorization, Content-Type, X-Request-ID]
credentials: true
max_age: 3600
# 常见错误:
# ❌ Access-Control-Allow-Origin: * (带凭证)
# ❌ 未经验证反映来源头部
# ❌ 允许所有方法/头部
第六阶段:版本控制 & 弃用
版本控制策略决策
| 策略 | 示例 | 优点 | 缺点 | 使用时 |
|---|---|---|---|---|
| URL路径 | /v1/orders |
明确,易于路由 | URL污染 | 公共API,多个主要版本 |
| 头部 | API-Version: 2024-01 |
清洁URL | 隐藏,更难测试 | 内部API |
| 查询参数 | ?version=2 |
易于测试 | 污染参数 | 快速原型 |
| 基于日期 | 2024-01-15 |
清晰的时间线 | 许多版本 | Stripe风格API |
推荐:URL路径用于主要版本,头部用于次要变化。
弃用剧本
时间线:
1. T+0: 宣布弃用(文档,变更日志,电子邮件)
2. T+0: 在旧端点添加弃用+日落头部
3. T+30d: 记录旧端点使用警告
4. T+60d: 直接通过电子邮件联系旧端点的重度用户
5. T+90d: 返回299警告头部
6. T+180d: 关闭旧端点(410 Gone)
头部:
Deprecation: true
Sunset: Sat, 01 Jun 2025 00:00:00 GMT
Link: <https://api.example.com/v2/orders>; rel="successor-version"
迁移指南模板
# 从v1迁移到v2
## 破坏性更改
1. `user.name`拆分为`user.first_name` + `user.last_name`
2. 分页从偏移量更改为基于游标的
3. 错误格式已更新(见新模式)
## 逐步迁移
1. 更新您的客户端SDK到v2(`npm install @example/sdk@2`)
2. 更新响应解析以拆分名称字段
3. 用`?after=cursor`分页替换`?page=N`
4. 更新错误处理以适应新的错误格式
## 兼容性模式
设置`X-Compat-Mode: v1`头部以从v2端点获得v1样式响应。
有效期至2025-06-01。
第七阶段:监控 & 可观察性
关键指标仪表板
availability:
- 正常运行时间百分比(目标:99.9% = 每年8.7小时停机时间)
- 健康检查状态(/health端点)
- 错误率(5xx / 总请求)
performance:
- p50延迟(目标:<100ms)
- p95延迟(目标:<500ms)
- p99延迟(目标:<1000ms)
- 吞吐量(每秒请求数)
- 第一个字节时间(TTFB)
business:
- 每个端点的请求(使用模式)
- 每天唯一的API消费者
- 每个端点的错误率
- 每天的速率限制命中
- 每天的认证失败
infrastructure:
- 数据库查询时间(p95)
- 连接池利用率
- 每个实例的内存/CPU
- 队列深度(异步操作)
结构化日志
每个请求应记录:
{
"timestamp": "2024-01-15T10:30:00.000Z",
"level": "info",
"request_id": "req_abc123",
"method": "POST",
"path": "/api/v1/orders",
"status": 201,
"duration_ms": 45,
"user_id": "usr_xyz",
"ip": "203.0.113.1",
"user_agent": "MyApp/2.0",
"request_size": 256,
"response_size": 1024
}
健康检查端点
// GET /health — 用于负载均衡器(简单)
{ "status": "ok" }
// GET /health/detailed — 用于监控(认证)
{
"status": "degraded",
"version": "1.5.2",
"uptime_seconds": 86400,
"checks": {
"database": { "status": "ok", "latency_ms": 5 },
"redis": { "status": "ok", "latency_ms": 2 },
"external_payment_api": { "status": "degraded", "latency_ms": 2500, "error": "timeout" },
"disk": { "status": "ok", "free_gb": 45.2 }
}
}
第八阶段:API审核评分
当审核现有API时,按这些维度评分:
API质量评分表(0-100)
| 维度 | 权重 | 标准 | 分数 |
|---|---|---|---|
| 设计一致性 | 20% | 命名约定,HTTP方法,状态码,URL结构 | /20 |
| 文档编制 | 15% | OpenAPI规范,示例,错误文档,变更日志 | /15 |
| 错误处理 | 15% | 一致的格式,有帮助的消息,适当的代码,无泄露 | /15 |
| 安全 | 20% | 认证,输入验证,CORS,头部,无IDOR | /20 |
| 性能 | 15% | 延迟目标达成,分页,缓存头部,N+1防止 | /15 |
| 开发者体验 | 15% | SDK质量,沙盒可用,上手时间,速率限制清晰度 | /15 |
分数: ___/100
| 评级 | 分数 | 行动 |
|---|---|---|
| 🟢 优秀 | 85-100 | 仅需要小幅改进 |
| 🟡 良好 | 70-84 | 下一个大版本前解决差距 |
| 🟠 需要工作 | 50-69 | 优先改进,创建技术债务票 |
| 🔴 严重 | <50 | 停止功能工作,首先修复基础 |
审核输出模板
## API审核:[服务名称]
**日期:** YYYY-MM-DD
**审核员:** [代理]
**分数:** XX/100(评级)
### 摘要
[对API质量的2-3句话概述]
### 按维度评分
- 设计一致性:X/20 — [关键发现]
- 文档编制:X/15 — [关键发现]
- 错误处理:X/15 — [关键发现]
- 安全:X/20 — [关键发现]
- 性能:X/15 — [关键发现]
- 开发者体验:X/15 — [关键发现]
### 紧急问题(立即修复)
1. [问题+建议]
### 高优先级(本冲刺修复)
1. [问题+建议]
### 锦上添花(待办事项)
1. [问题+建议]
### 积极亮点
- [什么做得好]
GraphQL特定指南
模式设计原则
# 好的:清晰的类型,适当的地方可空,连接用于列表
type Order {
id: ID!
status: OrderStatus!
customer: Customer!
items(first: Int, after: String): ItemConnection!
total: Money!
createdAt: DateTime!
updatedAt: DateTime!
}
type Money {
amount: Int! # 分,而不是美元(避免浮点)
currency: Currency!
}
enum OrderStatus {
DRAFT
CONFIRMED
PROCESSING
SHIPPED
DELIVERED
CANCELLED
}
# 变更返回修改后的资源+错误
type CreateOrderPayload {
order: Order
errors: [UserError!]!
}
type UserError {
field: [String!]
message: String!
code: ErrorCode!
}
GraphQL反模式
| 反模式 | 问题 | 修复 |
|---|---|---|
| 没有深度限制 | 查询炸弹 | 限制深度为5-7级 |
| 没有复杂性限制 | 昂贵的查询 | 每个字段分配成本,上限为1000 |
| N+1查询 | 性能死亡 | 使用DataLoader模式 |
| 没有持久化查询 | 安全风险 | 生产中白名单查询 |
| 暴露内部ID | 实现泄露 | 使用不透明的全局ID |
| 没有分页 | 内存爆炸 | 使用Relay连接规范 |
边缘情况 & 陷阱
时区处理
- 总是存储和返回UTC(ISO 8601:
2024-01-15T10:30:00Z) - 接受时区输入,立即转换为UTC
- 永远不要使用本地服务器时间
大负载
- 设置
Content-Length限制(例如,默认1MB,上传10MB) - 使用流式传输文件上传(multipart/form-data)
- 压缩响应(Accept-Encoding: gzip)
- 对于非常大的导出 → 返回202 + 轮询状态端点
最终一致性
- 如果使用异步处理,总是返回202 + 状态URL
- 可能的话包括预计完成时间
- 客户端应使用指数退避轮询
并发更新
- 使用ETags进行乐观并发:
- GET返回
ETag: "v1"头部 - PUT/PATCH发送
If-Match: "v1"头部 - 服务器返回412如果资源已更改
- GET返回
Webhook设计
- 包括事件类型、时间戳和完整资源在负载中
- 签名负载(HMAC-SHA256)
- 预期重试(使处理程序幂等)
- 快速返回200,异步处理
- 包括Webhook ID以供去重
快速命令
| 请求 | 动作 |
|---|---|
| “为[领域]设计API” | 运行第一阶段资源建模+命名 |
| “生成OpenAPI规范” | 运行第二阶段,使用完整的组件 |
| “审核这个API” | 运行第八阶段评分表 |
| “为[端点]编写测试” | 运行第四阶段端点清单 |
| “对这个API进行安全审计” | 运行第五阶段安全检查表 |
| “我应该如何对此进行版本控制?” | 运行第六阶段决策矩阵 |
| “调试这个API问题” | 检查第七阶段日志+健康模式 |
| “为[领域]设计GraphQL模式” | 运行GraphQL部分 |