api-design
REST API 设计最佳实践与模式指南,涵盖资源命名、HTTP 状态码语义、分页策略(Offset / Cursor)、过滤排序、标准化错误响应、API 版本管理(URL / Header)、限流策略及多语言实现示例,帮助构建一致、可扩展、开发者友好的生产级 API。
核心能力
生产级 REST API 设计规范与实现模式
提供从 URL 设计到部署运维的全流程 REST API 设计指南。覆盖资源命名、HTTP 语义、响应格式、分页策略、过滤搜索、认证授权、限流、版本管理等核心主题,附带 TypeScript、Python、Go 三种语言的实现示例。
适用场景
- 设计新的 API 端点
- 审查现有 API 契约
- 添加分页、过滤或排序能力
- 实现 API 错误处理
- 规划 API 版本管理策略
- 构建公开或面向合作伙伴的 API
资源命名规范
URL 结构原则
- 资源使用名词、复数、小写、kebab-case
- 嵌套资源表示从属关系
- 非 CRUD 操作谨慎使用动词
# 标准 CRUD
GET /api/v1/users
GET /api/v1/users/:id
POST /api/v1/users
PUT /api/v1/users/:id
PATCH /api/v1/users/:id
DELETE /api/v1/users/:id
# 嵌套资源
GET /api/v1/users/:id/orders
POST /api/v1/users/:id/orders
# 动作端点(慎用)
POST /api/v1/orders/:id/cancel
POST /api/v1/auth/login
命名对比
| 推荐 | 避免 |
|---|---|
/api/v1/team-members |
/api/v1/getUsers(URL 含动词) |
/api/v1/orders?status=active(查询参数过滤) |
/api/v1/user(单数) |
/api/v1/users/123/orders(嵌套所有权) |
/api/v1/team_members(snake_case) |
HTTP 方法与状态码
方法语义
| 方法 | 幂等 | 安全 | 用途 |
|---|---|---|---|
| GET | 是 | 是 | 获取资源 |
| POST | 否 | 否 | 创建资源、触发动作 |
| PUT | 是 | 否 | 完整替换资源 |
| PATCH | 可做到* | 否 | 部分更新资源 |
| DELETE | 是 | 否 | 删除资源 |
* PATCH 通过正确实现可达到幂等
状态码速查
| 类别 | 状态码 | 场景 |
|---|---|---|
| 成功 | 200 OK | GET、PUT、PATCH(带响应体) |
| 201 Created | POST(带 Location 头) | |
| 204 No Content | DELETE、PUT(无响应体) | |
| 客户端错误 | 400 Bad Request | 校验失败、JSON 格式错误 |
| 401 Unauthorized | 认证缺失或无效 | |
| 403 Forbidden | 已认证但无权访问 | |
| 404 Not Found | 资源不存在 | |
| 409 Conflict | 重复条目、状态冲突 | |
| 422 Unprocessable Entity | 语义无效(JSON 有效但数据错误) | |
| 429 Too Many Requests | 超出限流 | |
| 服务端错误 | 500 Internal Server Error | 意外失败(切勿暴露细节) |
| 502 Bad Gateway | 上游服务失败 | |
| 503 Service Unavailable | 临时过载(带 Retry-After) |
常见错误
# 错误:所有返回都 200
{ "status": 200, "success": false, "error": "Not found" }
# 正确:语义化使用 HTTP 状态码
HTTP/1.1 404 Not Found
{ "error": { "code": "not_found", "message": "User not found" } }
响应格式规范
成功响应
{
"data": {
"id": "abc-123",
"email": "alice@example.com",
"name": "Alice",
"created_at": "2025-01-15T10:30:00Z"
}
}
集合响应(带分页)
{
"data": [
{ "id": "abc-123", "name": "Alice" },
{ "id": "def-456", "name": "Bob" }
],
"meta": {
"total": 142,
"page": 1,
"per_page": 20,
"total_pages": 8
},
"links": {
"self": "/api/v1/users?page=1&per_page=20",
"next": "/api/v1/users?page=2&per_page=20",
"last": "/api/v1/users?page=8&per_page=20"
}
}
错误响应
{
"error": {
"code": "validation_error",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Must be a valid email address",
"code": "invalid_format"
},
{
"field": "age",
"message": "Must be between 0 and 150",
"code": "out_of_range"
}
]
}
}
分页策略
Offset 分页(简单型)
GET /api/v1/users?page=2&per_page=20
- 优点:易于实现,支持"跳转到第 N 页"
- 缺点:大偏移量性能差(OFFSET 100000),并发插入导致数据不一致
Cursor 分页(可扩展型)
GET /api/v1/users?cursor=eyJpZCI6MTIzfQ&limit=20
{
"data": [...],
"meta": {
"has_next": true,
"next_cursor": "eyJpZCI6MTQzfQ"
}
}
- 优点:任何位置性能一致,并发插入稳定
- 缺点:无法跳转到任意页,cursor 不透明
选型建议
| 场景 | 推荐分页 |
|---|---|
| 管理后台、小数据集(<10K) | Offset |
| 无限滚动、信息流、大数据集 | Cursor |
| 公开 API | Cursor(默认)+ Offset(可选) |
| 搜索结果 | Offset(用户期望页码) |
v1.0.0
2026-07-16
下载