本文目录导读:

- 核心设计原则
- 接口风格与协议选择
- URL与资源设计
- 请求与响应规范
- 安全与认证
- 错误码设计
- 版本管理
- 文档与工具
- 一个完整的API设计示例
- 进阶实践:GraphQL
- 总结:优秀API Checklist
设计一个优秀的开放API需要兼顾易用性、稳定性、安全性和可扩展性,下面是一个从零到一的系统性设计指南,涵盖了从HTTP规范到文档、SDK的完整流程。
核心设计原则
- 面向资源设计:把API看作对资源的操作,而不是RPC(远程过程调用)。
- 一致性:URL路径、请求/响应格式、错误码、分页方式都保持一致。
- 版本控制:保证向后兼容,允许API平滑演进。
- 无状态:每个请求都包含所有必要信息,服务器的会话状态不依赖客户端。
- 安全第一:认证、授权、限流、数据校验。
接口风格与协议选择
目前主流的选择是 RESTful API,对于复杂、强类型、高数据交互的场景(如内部微服务、给前端用的复杂查询)推荐 GraphQL,对于低延迟、高频次场景(如实时聊天、游戏数据同步)选择 WebSocket。
| 特性 | RESTful | GraphQL | WebSocket |
|---|---|---|---|
| 数据获取 | 服务端定义返回结构 | 客户端精确查询所需字段 | 双向流式推送 |
| 缓存 | 天然支持HTTP缓存 | 缓存复杂,需要客户端处理 | 不适用 |
| 版本管理 | URL (/v1/) 或 Header | 无需版本,通过Schema演进 | 协议协商 |
| 典型场景 | 标准业务CRUD、公开API | 复杂数据仪表盘、移动端 | 实时通知、直播、协同编辑 |
URL与资源设计
遵循RESTful规范,使用名词复数表示资源,用HTTP动词表示操作。
正确姿势
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}/activate(激活用户,用动词表示动作) - 搜索:
GET /api/v1/orders?status=paid&page=1&size=20 - 字段筛选:
GET /api/v1/users?fields=id,name,email
常见错误设计
GET /api/getUsers(动词在URL中)POST /api/deleteUser(删除用了POST)GET /api/v1/usersAPI(混合术语)
请求与响应规范
统一响应格式
使用统一的JSON结构包裹数据,方便客户端统一解析。
成功响应 (HTTP 2xx)
{
"code": 0,
"message": "success",
"data": {
"id": 123,
"name": "张三",
"email": "zhangsan@example.com"
}
}
列表响应(带分页)
{
"code": 0,
"message": "success",
"data": {
"items": [ ... ],
"pagination": {
"page": 1,
"size": 20,
"total": 100,
"total_pages": 5
}
}
}
错误响应 (HTTP 4xx/5xx)
{
"code": 1001,
"message": "参数校验失败",
"errors": [
{ "field": "email", "message": "邮箱格式不正确" }
]
}
HTTP状态码使用指南
| 状态码 | 含义 | 使用场景 |
|---|---|---|
| 200 | OK | 请求成功 |
| 201 | Created | 资源创建成功(POST) |
| 204 | No Content | 删除/更新成功,无返回体(DELETE/PUT) |
| 301/302 | Redirect | 资源地址变更 |
| 400 | Bad Request | 客户端参数错误、校验失败 |
| 401 | Unauthorized | 未认证(缺少Token或Token过期) |
| 403 | Forbidden | 已认证但无权限 |
| 404 | Not Found | 资源不存在 |
| 409 | Conflict | 资源冲突(如重复创建、版本冲突) |
| 422 | Unprocessable Entity | 语义错误(如业务逻辑校验失败) |
| 429 | Too Many Requests | 限流触发 |
| 500 | Internal Server Error | 服务端未捕获的异常 |
安全与认证
认证方案
- API Key:简单易用,通过Header
X-API-Key或Query参数传递,适合低安全要求的公开数据。 - JWT (JSON Web Token):最常用、无状态的认证方式,服务端签发Token,客户端每次请求在
Authorization: Bearer <token>中携带。 - OAuth 2.0:用于“授权第三方应用访问用户数据”,支持授权码、客户端凭证、隐式授权等模式,公开API强烈建议使用。
常见安全措施
- HTTPS强制:所有API必须通过TLS加密。
- 限流 (Rate Limiting):通过Header返回剩余配额。
X-RateLimit-Limit: 100X-RateLimit-Remaining: 99X-RateLimit-Reset: 1626123456
- 输入校验:服务端对所有参数进行白名单校验,防止SQL注入、XSS攻击。
- CORS配置:开放给前端调用时,正确配置
Access-Control-Allow-Origin。 - 敏感数据脱敏:返回数据时,对密码、手机号、身份证等做掩码处理。
错误码设计
使用业务错误码(4-5位数字)而非HTTP状态码直接替代,因为HTTP状态码有限,不足以表达细粒度的业务错误。
# 通用错误 1000: 系统内部错误 1001: 参数校验失败 # 认证授权 2001: Token无效或过期 2002: 无权限操作 # 业务错误 (以订单模块为例) 3001: 订单不存在 3002: 订单已支付,无法取消 3003: 库存不足
版本管理
明确的版本号是API演进的基石。
- 推荐方式:URL路径版本号
https://api.example.com/v1/orders - 备选方式:自定义Header
Accept: application/vnd.example.v1+json
文档与工具
API设计出来,没人会用等于白费,推荐使用OpenAPI规范(原Swagger)来描述API。
- 工具选择:
- Swagger UI:自动生成交互式文档,开发者可以在线调试。
- Stoplight:更现代、协作性强的API设计平台。
- Postman:提供集成的文档发布和测试环境。
文档必须包含的内容
- 基础URL 和 版本号。
- 认证方式(如何获取和传递Token)。
- 每个接口的:方法、URL、请求参数(Query/Header/Body)、响应示例、错误码。
- 限流策略。
- 代码示例(至少提供curl、Python、JavaScript)。
一个完整的API设计示例
假设我们要设计一个“用户订单管理”API的 /v1/orders 接口:
基础URL: https://api.example.com/v1
认证: Bearer Token in Authorization Header
创建订单
- POST
/orders - Request Body:
{ "product_id": "prod_123", "quantity": 2, "shipping_address": "北京市朝阳区..." } - Response (201):
{ "code": 0, "message": "success", "data": { "order_id": "ord_456", "status": "pending", "total_price": 199.98, "created_at": "2023-10-27T10:00:00Z" } }
查询订单列表
- GET
/orders?status=paid&page=1&size=20 - Response (200):
{ "code": 0, "message": "success", "data": { "items": [ { ... } ], "pagination": { "page": 1, "size": 20, "total": 50 } } }
进阶实践:GraphQL
如果你选择GraphQL,设计思路会变成:定义Schema -> 实现Resolver -> 客户端按需查询,它的核心优势是避免了冗余数据和多个请求的拼接。
// 客户端只需这样查询,就能一次性获得用户、订单、商品信息
{
user(id: "123") {
name
orders {
id
total
items {
product {
name
price
}
}
}
}
}
优秀API Checklist
- [ ] 符合直觉:URL、动词、参数命名清晰易懂。
- [ ] 一致性强:所有接口遵守相同规范。
- [ ] 健壮:有完善的错误处理、限流、安全加密。
- [ ] 有文档:自动生成、随时更新的交互式文档。
- [ ] 可测试:提供沙箱环境、Mock数据或测试Key。
设计API时,可以时刻换位思考:“如果我是一个刚接触这个API的新手,我能不看文档就猜出这个接口怎么用吗?” 如果能,那就算成功了。