好的 API 设计让调用方心情愉悦,坏的 API 让他们想砸键盘。这篇文章总结 10 条实战验证的设计原则。
URL 设计原则
- 用名词复数而非动词 —
GET /users不是GET /getUsers。HTTP 方法已经表达了动作。 - 层级关系用嵌套 URL —
GET /users/123/orders清晰表达了"用户 123 的订单"。 - 不要超过 3 层 —
/users/123/orders/456/items太深了,这种情况拆成/orders/456/items。 - 用 kebab-case 不用 camelCase —
/shipping-address不是/shippingAddress。SEO 友好,肉眼易读。
HTTP 方法正确使用
| 方法 | 操作 | 幂等? | 示例 |
|---|---|---|---|
| GET | 读取 | ✅ | GET /articles |
| POST | 创建 | ❌ | POST /articles |
| PUT | 全量更新 | ✅ | PUT /articles/1 |
| PATCH | 部分更新 | ❌ | PATCH /articles/1 |
| DELETE | 删除 | ✅ | DELETE /articles/1 |
响应格式规范
{
"data": { "id": 1, "title": "..." },
"meta": { "page": 1, "per_page": 20, "total": 150 },
"errors": null
}
错误处理
- 用正确的 HTTP 状态码 — 400 参数错误、401 未认证、403 无权限、404 不存在、422 参数校验失败、429 频率限制、500 服务器错误。
- 错误信息结构化 — 返回
{"errors":[{"code":"VALIDATION_ERROR","field":"email","message":"邮箱格式不正确"}]},不要只返回一个字符串。
五大常见反模式
- 所有操作都用 POST — 这是 RPC 不是 REST
- 返回所有字段 — 支持
?fields=id,title让客户端选择需要的字段 - 不版本化 — URL 加
/v1/前缀或在 Header 中指定版本 - 不限制分页 —
per_page最大 100,防止一次请求拖垮数据库 - 不写 API 文档 — OpenAPI/Swagger 规范是标配