Appearance
API 设计与接口规范
这篇用于沉淀接口设计时真正会反复复用的通用规范。重点不是背标准原文,而是把日常做接口时最容易反复讨论的点收口成一套可执行规则。
一、先定设计原则
接口设计最怕两种情况:
- 只顾着把功能做出来,没有统一风格,最后每个接口都像不同人写的。
- 过度追求“完美规范”,结果文档和实现完全脱节。
实际落地时,更适合抓住下面 5 条:
- 资源优先:先想清楚系统里有哪些资源,再定义接口,而不是先写一堆动作型 URL。
- HTTP 语义清晰:
GET查、POST建、PUT/PATCH改、DELETE删,避免“全站一个 POST”。 - 返回结构稳定:前端和调用方最怕字段风格、错误格式、分页结构来回变。
- 文档和实现同源:能从代码或配置生成文档,就不要维护两套真相。
- 先统一最常用的 80%:命名、状态码、鉴权、分页、错误响应优先统一,细节扩展后补。
二、URL 设计的基本规则
1. 按资源建模
推荐:
/users/orders/orders/{id}/orders/{id}/items
不推荐:
/getUserList/saveOrder/deleteOrderById
原因很简单:资源化 URL 更稳定,也更容易配合文档、权限、版本控制和 SDK 生成。
2. 名称统一
- 路径尽量用小写英文和
kebab-case - 集合用复数更自然,比如
users、orders - 避免中英混用、拼音缩写、项目内部黑话
3. 查询参数只做“筛选/排序/分页”
例如:
text
GET /orders?status=paid&page=1&pageSize=20&sort=createdAt:desc不要把“修改状态”“确认收货”这类动作塞进查询参数。
三、HTTP 方法怎么用
| 方法 | 用途 | 常见场景 |
|---|---|---|
GET | 查询资源 | 列表、详情 |
POST | 创建资源 / 执行动作 | 新增、导入、发起任务 |
PUT | 整体更新 | 用完整对象覆盖 |
PATCH | 部分更新 | 更新状态、改单个字段 |
DELETE | 删除资源 | 逻辑删除 / 物理删除 |
实践建议:
- 如果只是查数据,不要用
POST - 如果是“执行动作”,要明确它不是普通 CRUD,例如
/orders/{id}:cancel - 如果团队还不习惯
PATCH,可以统一退回PUT+ 明确字段约束,但不要同一系统混着乱用
四、请求与响应建议
1. 请求体
- 字段命名统一一种风格,推荐
camelCase - 时间字段统一格式,优先 ISO 8601
- 金额、数量、状态等关键字段类型要稳定,不要今天是字符串,明天是数字
2. 响应体
如果是面向业务系统的内部接口,建议保持统一响应信封,例如:
json
{
"success": true,
"code": "OK",
"message": "",
"data": {
"id": 1001,
"name": "demo"
}
}如果是更偏开放平台或标准化接口,可以尽量贴近 JSON:API / OpenAPI 这类规范,但前提是团队真的能持续遵守。
3. 分页结构
分页尽量固定,不要每个接口自己定义一套:
json
{
"success": true,
"data": {
"items": [],
"page": 1,
"pageSize": 20,
"total": 135
}
}五、状态码与错误响应
状态码不用追求花样多,先把最常用的定义稳定:
| 状态码 | 含义 | 说明 |
|---|---|---|
200 | 成功 | 查询、更新成功 |
201 | 创建成功 | 新增资源 |
400 | 请求参数错误 | 字段缺失、格式错误 |
401 | 未认证 | Token 缺失或失效 |
403 | 无权限 | 已登录但无权访问 |
404 | 资源不存在 | ID 无效或已删除 |
409 | 冲突 | 唯一键冲突、状态冲突 |
500 | 服务端异常 | 未处理异常 |
错误响应建议至少统一这几项:
json
{
"success": false,
"code": "ORDER_STATUS_INVALID",
"message": "当前订单状态不允许取消",
"details": null
}重点:
message给人看code给程序判断- 不要把数据库报错、堆栈信息直接透出到外部接口
六、版本控制怎么做
接口版本控制通常只在这几种情况值得上:
- 对外开放接口,调用方多,兼容性要求高
- 同一资源模型要长期演进
- 老客户端无法同步升级
常见做法:
- URL 版本:
/api/v1/orders - Header 版本:
Accept: application/vnd.company.v1+json
如果只是内部系统、调用方可控,没必要一开始就做复杂版本治理。 更实际的策略是:先把字段设计稳住,再决定是否需要显式版本号。
七、文档化建议
接口文档至少要解决 4 个问题:
- 这个接口是干什么的
- 需要哪些参数
- 返回什么结构
- 错误时会给什么响应
在 .NET / Java 项目里,推荐优先用 OpenAPI 体系生成文档,再人工补充说明。 这样能保证“文档和代码尽量同源”,比单独维护 Word/Markdown 接口表可靠得多。
八、用 curl 做最小验证
接口设计完之后,最好先用 curl 做最小可用验证。 原因很简单:curl 不依赖图形界面,最容易暴露请求方法、Header、参数和返回体是否真的设计合理。
例如:
bash
curl -X GET "https://api.example.com/orders/1001" \
-H "Authorization: Bearer <token>" \
-H "Accept: application/json"如果一个接口连 curl 都很难说明白,通常意味着接口设计还不够清晰。
九、什么时候参考 JSON:API / OpenAPI
JSON:API 适合看什么
- 资源关系怎么表达
- 响应结构如何保持一致
- 包含关联资源时怎么展开
OpenAPI 适合看什么
- 如何描述接口契约
- 如何生成文档
- 如何给前后端、测试、SDK 提供统一接口定义
简单理解:
- JSON:API 更偏响应风格和资源表达
- OpenAPI 更偏接口描述和文档契约
十、自己以后复用时最该统一的清单
以后写新接口,优先先对齐下面这份清单:
- URL 命名规则
- 请求方法使用规则
- 分页结构
- 错误响应格式
- 状态码使用范围
- 鉴权方式
- 时间与金额字段格式
- OpenAPI 文档生成方式
只要这 8 项统一,接口系统的可维护性就会明显提升。
