api-design-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAPI Design Patterns
API设计模式
Resource Naming
资源命名
- Use plural nouns: ,
/users,/orders/products - Nest for relationships:
/users/{id}/orders - Max nesting depth: 2 levels. Beyond that, use query params or top-level resources
- Use kebab-case: , not
/user-profiles/userProfiles - Never put verbs in URLs: is wrong, use
/users/{id}/activatePOST /users/{id}/activation
- 使用复数名词:、
/users、/orders/products - 为关联关系使用嵌套结构:
/users/{id}/orders - 最大嵌套深度:2层。超过此深度,使用查询参数或顶级资源
- 使用短横线分隔(kebab-case):,而非
/user-profiles/userProfiles - 绝不要在URL中使用动词:是错误的,应使用
/users/{id}/activatePOST /users/{id}/activation
HTTP Methods
HTTP方法
| Method | Purpose | Idempotent | Request Body | Success Code |
|---|---|---|---|---|
| GET | Read resource(s) | Yes | No | 200 |
| POST | Create resource | No | Yes | 201 |
| PUT | Full replace | Yes | Yes | 200 |
| PATCH | Partial update | No | Yes | 200 |
| DELETE | Remove resource | Yes | No | 204 |
Return header on POST with the URL of the created resource.
Location| 方法 | 用途 | 幂等性 | 请求体 | 成功状态码 |
|---|---|---|---|---|
| GET | 读取资源(一个或多个) | 是 | 无 | 200 |
| POST | 创建资源 | 否 | 有 | 201 |
| PUT | 完全替换资源 | 是 | 有 | 200 |
| PATCH | 部分更新 | 否 | 有 | 200 |
| DELETE | 删除资源 | 是 | 无 | 204 |
POST请求成功后返回头,包含创建资源的URL。
LocationStatus Codes
状态码
200 OK - Successful read/update
201 Created - Successful creation
204 No Content - Successful delete
400 Bad Request - Validation error (include field-level errors)
401 Unauthorized - Missing or invalid authentication
403 Forbidden - Authenticated but not authorized
404 Not Found - Resource does not exist
409 Conflict - State conflict (duplicate, version mismatch)
422 Unprocessable - Semantically invalid (valid JSON, bad values)
429 Too Many Reqs - Rate limited (include Retry-After header)
500 Internal Error - Unhandled server error (never expose stack traces)200 OK - 读取/更新成功
201 Created - 创建成功
204 No Content - 删除成功
400 Bad Request - 验证错误(包含字段级错误)
401 Unauthorized - 缺少或无效的身份认证
403 Forbidden - 已认证但无权限
404 Not Found - 资源不存在
409 Conflict - 状态冲突(重复、版本不匹配)
422 Unprocessable - 语义无效(JSON格式合法,但值不合法)
429 Too Many Reqs - 请求超限(包含Retry-After头)
500 Internal Error - 未处理的服务器错误(绝不要暴露堆栈跟踪)Error Response Format
错误响应格式
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "field": "email", "message": "Must be a valid email address" },
{ "field": "age", "message": "Must be at least 18" }
]
}
}Use consistent error codes across the API. Document every code in your API reference.
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "field": "email", "message": "Must be a valid email address" },
{ "field": "age", "message": "Must be at least 18" }
]
}
}在整个API中使用一致的错误码。在API参考文档中记录每个错误码。
Cursor-Based Pagination (preferred)
基于游标分页(推荐)
GET /users?limit=20&cursor=eyJpZCI6MTAwfQ
Response:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTIwfQ",
"has_more": true
}
}Use cursor pagination for large or frequently changing datasets. Encode cursors as opaque base64 strings. Never expose raw IDs in cursors.
GET /users?limit=20&cursor=eyJpZCI6MTAwfQ
Response:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTIwfQ",
"has_more": true
}
}对于大型或频繁变更的数据集,使用游标分页。将游标编码为不透明的base64字符串。绝不要在游标中暴露原始ID。
Offset-Based Pagination (simple cases only)
基于偏移量分页(仅适用于简单场景)
GET /users?page=3&per_page=20
Response:
{
"data": [...],
"pagination": {
"page": 3,
"per_page": 20,
"total": 245,
"total_pages": 13
}
}Only use offset pagination when total count is cheap and dataset is small.
GET /users?page=3&per_page=20
Response:
{
"data": [...],
"pagination": {
"page": 3,
"per_page": 20,
"total": 245,
"total_pages": 13
}
}仅当总计数获取成本低且数据集较小时,才使用偏移量分页。
Filtering and Sorting
过滤与排序
GET /orders?status=pending&created_after=2025-01-01&sort=-created_at,+total
GET /products?category=electronics&price_min=100&price_max=500
GET /users?search=john&fields=id,name,emailUse field selection ( param) to reduce payload size. Prefix sort fields with for descending.
fields-GET /orders?status=pending&created_after=2025-01-01&sort=-created_at,+total
GET /products?category=electronics&price_min=100&price_max=500
GET /users?search=john&fields=id,name,email使用字段选择(参数)来减少响应体大小。排序字段前缀加表示降序。
fields-Versioning
版本控制
Prefer URL path versioning for simplicity:
/api/v1/users
/api/v2/usersRules:
- Never break v1 once published. Add fields, never remove them.
- New required fields = new version
- Deprecate old versions with header and 6-month notice
Sunset - Support at most 2 active versions simultaneously
推荐使用URL路径版本控制以简化操作:
/api/v1/users
/api/v2/users规则:
- 一旦发布,绝不要破坏v1版本。可以添加字段,但绝不要删除字段。
- 新增必填字段 = 新版本
- 使用头和6个月的通知来弃用旧版本
Sunset - 同时最多支持2个活跃版本
Request/Response Headers
请求/响应头
Content-Type: application/json
Accept: application/json
Authorization: Bearer <token>
X-Request-Id: <uuid> # For tracing
X-RateLimit-Limit: 100 # Requests per window
X-RateLimit-Remaining: 47 # Remaining in window
X-RateLimit-Reset: 1700000000 # Window reset Unix timestamp
Retry-After: 30 # Seconds until rate limit resetsAlways return in responses for debugging.
X-Request-IdContent-Type: application/json
Accept: application/json
Authorization: Bearer <token>
X-Request-Id: <uuid> # 用于追踪
X-RateLimit-Limit: 100 # 窗口期内最大请求数
X-RateLimit-Remaining: 47 # 窗口期内剩余请求数
X-RateLimit-Reset: 1700000000 # 窗口期重置的Unix时间戳
Retry-After: 30 # 限流重置前的等待秒数始终在响应中返回用于调试。
X-Request-IdOpenAPI Spec Guidelines
OpenAPI规范指南
- Write spec first, then implement (spec-driven development)
- Use for shared schemas:
$ref$ref: '#/components/schemas/User' - Define for every endpoint
examples - Use /
oneOffor polymorphic responsesanyOf - Generate client SDKs from the spec, never hand-write them
- Validate requests against the spec in middleware
yaml
paths:
/users/{id}:
get:
operationId: getUser
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'- 先编写规范,再实现(规范驱动开发)
- 对共享模式使用:
$ref$ref: '#/components/schemas/User' - 为每个端点定义
examples - 对多态响应使用/
oneOfanyOf - 从规范生成客户端SDK,绝不要手写
- 在中间件中根据规范验证请求
yaml
paths:
/users/{id}:
get:
operationId: getUser
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'Rate Limiting Strategy
限流策略
- Apply per-user, per-endpoint limits
- Use sliding window algorithm (not fixed window)
- Return with
429headerRetry-After - Exempt health check and auth endpoints from rate limits
- Log rate-limited requests for abuse detection
- 按每个用户、每个端点应用限流
- 使用滑动窗口算法(而非固定窗口)
- 返回状态码并附带
429头Retry-After - 健康检查和认证端点豁免限流
- 记录被限流的请求以检测滥用