RESTful API 设计原则
概述
RESTful API 设计是一种架构风格和一组约束条件,用于构建强调一致性、可扩展性和开发者体验的 Web 服务。这项技能提供了全面的指导,包括 REST 原则、HTTP 方法语义、URL 结构、状态代码、认证、分页和文档,以创建直观、可维护且随时间优雅演进的 API。
为什么这很重要
- 促进生态系统增长:一致的、文档齐全的 API 允许第三方开发者轻松集成您的平台
- 减少集成摩擦:清晰的模式和标准响应格式减少开发者混乱和集成错误
- 改善开发者体验:可预测的 URL、清晰的错误消息和直观设计使 API 易于使用
- 支持可扩展性:适当的资源建模和架构模式使系统能够在无需重大重新设计的情况下增长
- 确保客户端兼容性:版本控制策略和向后兼容性政策防止破坏现有消费者
- 降低支持成本:自文档化 API 和标准化响应减少文档负担和支持工单量
核心概念
1. 资源优先思维
围绕资源(名词)而非动作(动词)设计 API:
- 资源识别:用户、订单、产品、支付(而不是 getUsers、createOrder)
- 名词优于动词:使用 HTTP 方法表示动作(GET、POST、PUT、DELETE)
- 层次化资源:通过 URL 结构表示父子关系(users/123/orders)
- 一致命名:复数名词、小写、多词资源使用 kebab-case
2. HTTP 语义
根据其预定含义使用 HTTP 方法:
- GET:检索资源(幂等、安全、无副作用)
- POST:创建资源(非幂等、不安全、更改服务器状态)
- PUT:替换整个资源(幂等、不安全、完全替换)
- PATCH:部分更新(非幂等、不安全、选择性更新)
- DELETE:移除资源(幂等、不安全)
3. 无状态
每个请求包含处理它所需的所有信息:
- 无服务器会话状态:服务器不存储客户端会话状态
- 自包含请求:每个请求都包含所有上下文
- 可扩展性:无状态设计使水平扩展成为可能
- 提高可靠性:无会话亲和性问题或会话超时复杂性
4. 统一接口
与资源交互的一致方式:
- 一致的 URL:基于资源的 URL 结构
- 标准化响应:一致的响应信封格式
- HATEOAS:超媒体作为应用程序状态的引擎(可选)
- 标准错误:所有端点一致的错误响应格式
5. 版本控制
从第一天起就规划 API 演进:
- URL 路径版本控制:
/api/v1/users,/api/v2/users(推荐) - 头部版本控制:
Accept: application/vnd.api+json; version=1或X-API-Version: 1 - 语义版本控制:MAJOR.MINOR.PATCH(1.0.0, 1.1.0, 2.0.0)
- 弃用政策:通过日落头宣布弃用并保持向后兼容性窗口
6. 默认安全
从一开始就构建安全的 API:
- 仅 HTTPS:在生产中强制 HTTPS,将 HTTP 重定向到 HTTPS
- 认证:根据用例实施 JWT、OAuth 2.0 或 API 密钥
- 授权:基于角色的访问控制(RBAC)以访问资源
- 输入验证:验证和清理所有输入(参数化查询、类型检查)
- 输出编码:编码输出以防止 XSS 攻击
- 速率限制:通过每个用户或每个端点的速率限制防止滥用
- 安全头部:CSP、X-Frame-Options、X-Content-Type-Options
快速开始
- 定义资源:确定 API 将公开的所有资源(名词);定义它们的属性和关系
- 设计端点:将 HTTP 方法映射到资源操作(GET /users, POST /users, PUT /users/:id, DELETE /users/:id)
- 定义请求/响应格式:为请求创建一致的 JSON 模式,并标准化响应信封
- 定义错误处理:建立错误响应格式,包括错误代码、消息和详细信息;映射到适当的 HTTP 状态代码
- 实施认证/授权:为受保护的资源添加认证中间件和授权检查
- 添加速率限制:实现速率限制头部(X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset)和 429 响应
- 编写文档:创建 OpenAPI/Swagger 规范,包括请求/响应示例和错误代码
- 测试 API:使用单元和集成测试测试所有端点;验证认证、授权、速率限制和错误处理
- 部署和监控:部署 API 并配置日志、指标和监控以进行性能和错误监控
// 标准错误响应格式
interface ErrorResponse {
error: {
code: string; // 机器可读错误代码
message: string; // 人类可读消息
details?: ErrorDetail[];// 字段级错误
requestId?: string; // 用于调试/支持
timestamp?: string; // 错误发生时
};
}
interface ErrorDetail {
field: string;
message: string;
code?: string;
}
// 示例实现
app.use('/api', (req, res) => {
try {
const data = await someOperation();
res.json({ data });
} catch (error) {
const requestId = req.headers['x-request-id'];
res.status(422).json({
error: {
code: 'VALIDATION_ERROR',
message: '请求验证失败',
requestId,
details: [
{ field: 'email', message: '必须是有效的电子邮件地址' },
{ field: 'age', message: '必须在 18 到 120 之间', code: 'OUT_OF_RANGE' }
]
}
});
}
});
生产检查表
- [ ] 基于资源的 URL 结构(名词、复数、小写、kebab-case)
- [ ] 根据语义含义使用 HTTP 方法(GET 用于检索,POST 用于创建等)
- [ ] 适当的 HTTP 状态代码(2xx 成功,4xx 客户端错误,5xx 服务器错误)
- [ ] 一致的请求/响应格式(JSON,标准错误信封)
- [ ] 实施分页(推荐使用基于游标的大数据集)
- [ ] 支持过滤和排序(查询参数用于过滤,排序参数)
- [ ] 实施认证和授权(JWT、OAuth 2.0、RBAC)
- [ ] 实施速率限制(每个用户和每个端点的限制)
- [ ] 正确配置 CORS
- [ ] 在所有端点上进行输入验证和清理
- [ ] 配置安全头部(CSP、X-Frame-Options、X-Content-Type-Options)
- [ ] 在生产中强制 HTTPS
- [ ] 完整的 OpenAPI/Swagger 文档,包括示例
- [ ] 所有端点一致的错误响应格式
- [ ] 定义版本控制策略(推荐 URL 路径版本控制)
- [ ] 配置 API 监控和日志
- [ ] 返回速率限制头部(X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Window)
- [ ] 适当设置缓存头部(Cache-Control)
反模式
- 在 URL 中使用动词:
/api/getUsers,/api/createUser,/api/deleteUser而不是/api/users,/api/users,/api/users/:id - 不一致的命名约定:混合使用 camelCase、kebab-case 和大写(
/api/UserProfile,/api/order_items) - 深层 URL 嵌套:超过 2-3 级,如
/api/users/123/orders/456/items/789/details - 返回错误的状态代码:使用 200 表示错误或使用 500 表示客户端错误而不是适当的 4xx 代码
- 列表端点缺少分页:一次性返回所有记录,没有分页
- 过度使用 POST:使用 POST 进行检索而不是 GET
- 不一致的错误响应:不同的错误格式或没有一致的错误信封
- 忽略幂等性:使用 POST 更新或不考虑幂等操作
- 暴露内部实现:在 URL 中暴露数据库结构(
/api/user_profiles,/api/user_roles_map) - 没有版本控制策略:未经版本控制的破坏性更改,导致所有客户端的破坏性更改
集成点
- API 文档:OpenAPI/Swagger、Postman、Insomnia、Redoc 用于 API 文档和测试
- API 网关:Kong、AWS API Gateway、Azure API Management 用于路由、速率限制、缓存和认证
- 监控:Datadog、New Relic、Prometheus、Grafana 用于 API 监控和警报
- 认证:
jwt-authentication用于 JWT 实现模式 - 错误处理:
error-handling用于后端错误处理策略 - 验证:
validation用于输入验证模式 - API 风格指南:
api-style-guide用于组织范围内的 API 约定 - 速率限制:内置于 API 网关或使用库实现(express-rate-limit, ratelimiter)
- 安全:
owasp-top-10用于安全最佳实践 - 测试:API 测试工具和策略,确保 API 质量
进一步阅读
- REST API 教程 - 综合 REST API 教程和最佳实践
- MDN Web Docs - HTTP - 完整的 HTTP 参考
- OpenAPI 规范 - OpenAPI 3.0 规范
- RFC 7231 - HTTP 语义 - 官方 HTTP 语义 RFC
- Google API 设计指南 - Google 的 API 设计原则
- Microsoft REST API 指南 - Microsoft 的 REST API 指南
- Zalando RESTful API 指南 - 综合 REST 指南
- Heroku 平台 API 风格指南 - Heroku 的 API 风格指南