后端开发

REST API 设计的十条实用原则

2026-08-13 #API#REST#架构

用一致的资源模型、错误格式和演进策略降低协作成本。

核心思路

路径表达资源,HTTP 方法表达动作;分页、过滤和排序保持统一。错误响应包含稳定代码与可读信息,但不泄露内部堆栈。

落地步骤

兼容性优先于追求完美。通过契约测试和弃用周期管理变更,幂等接口要明确幂等键与有效期。

验证清单

实施后不要只确认“能运行”,还应检查错误率、延迟、资源占用和异常路径。把验证命令、预期结果和回滚方式写进变更记录,后续维护会轻松很多。

小结

好的工程实践不是堆叠工具,而是用清晰边界、可观察结果和可逆变更降低长期成本。先解决最重要的问题,再逐步自动化。

可执行实践

资源路径使用名词,方法表达动作;分页、过滤、排序和错误 envelope 在全站统一。写接口设计幂等键,错误返回稳定业务码和可追踪 request_id。

验证与退出条件

先写 OpenAPI 契约并做消费者测试。版本演进优先兼容新增字段,删除或改变语义要经过弃用期和调用方数据验证。

实践场景

以“设计一个可演进的订单查询 API”为例。实施前先保存当前版本、配置和关键指标基线,写明成功条件与停止条件;涉及生产数据或外部写入时,先在隔离环境验证。

分步实施

资源命名稳定,分页与过滤有明确上限;错误返回机器码和 trace 标识;新增字段保持向后兼容,幂等写操作接收业务键。每完成一步都记录可观察结果,不把命令返回零等同于业务正确。

故障演练

用旧客户端调用新服务,测试重复提交、非法分页、部分依赖失败和超时取消。演练应使用可清理的测试数据,并验证告警、日志和恢复路径,而不只是确认系统最终又能访问。

观测与回滚

观察错误码分布、兼容失败和重试次数;破坏性变更使用新版本并保留迁移窗口。变更单中应写清负责人、观察窗口、阈值和回滚触发器,避免故障发生后再临时争论。

完成后把使用的版本、关键命令、观测窗口和结果写入变更记录。没有验证证据的“已完成”不能作为上线结论。

第二轮实践复核

可复用交付物: OpenAPI 契约、兼容性样本和幂等测试。复用时先固定软件版本、依赖锁文件、测试数据规模和运行环境;文章中的命令包含占位符,必须替换成自己的非生产目标后再执行。

最低验证: 用旧客户端契约测试新服务,并重复提交相同幂等键

执行记录要保存命令、退出码、关键输出、观察窗口和回滚结果。若验证会产生写入,先使用隔离环境或 dry-run;任何失败都不能通过扩大权限、关闭校验或跳过测试来“解决”。

完整实战:订单创建与查询 API

假设要为结算页提供“创建订单”和“查询订单”两个接口。先把业务不变量写进契约:金额由服务端按商品快照计算;同一个结算动作只生成一张订单;客户端超时后可以安全重试;调用方能够区分参数错误、库存冲突和依赖暂时不可用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
paths:
/orders:
post:
parameters:
- in: header
name: Idempotency-Key
required: true
schema: { type: string, minLength: 16, maxLength: 64 }
responses:
"201": { description: created }
"409": { description: idempotency key reused with different payload }
/orders/{order_id}:
get:
responses:
"200": { description: found }
"404": { description: not found }

幂等记录不能只保存“这个键见过”,还应绑定租户、调用方、请求摘要、响应和过期时间。同一键与同一摘要再次到达时返回原结果;同一键对应不同摘要时返回冲突,不能悄悄创建第二张订单。

统一错误 envelope,HTTP 状态表达协议语义,稳定业务码供程序分支,request_id 用于串联日志:

1
2
3
4
5
6
7
8
{
"error": {
"code": "INVENTORY_NOT_ENOUGH",
"message": "部分商品库存不足",
"request_id": "req_01J...",
"details": [{ "sku": "SKU-42", "available": 1 }]
}
}

分页、并发修改与兼容

  • 列表数据持续变化时优先游标分页;游标应不可伪造,并固定排序字段与并列项规则。
  • 更新接口可接受 If-Match/版本号,旧版本提交返回冲突,防止后写覆盖先写。
  • 新增可选响应字段通常可兼容,重命名字段、收紧枚举和改变 null 语义都可能破坏旧客户端。
  • 写操作不要用模糊的 200 表示所有结果;创建、异步接受、无响应体应分别使用与语义相符的状态。

契约回归矩阵

用例 请求 预期证据
首次创建 新幂等键 + 合法载荷 一条订单、201、审计事件一条
网络重试 相同键 + 相同载荷 同一订单号,业务副作用不增加
错误复用 相同键 + 不同载荷 409,原订单不变化
旧客户端 删除新增可选字段后调用 仍能解析成功响应
并发更新 两个相同旧版本号 只有一个成功,另一个冲突

发布时先让提供方通过 OpenAPI 校验与消费者契约,再观察业务码分布、P95 延迟和幂等冲突率。回滚应用版本时不要同步删除新字段或幂等记录;数据结构的向后兼容窗口必须长于应用灰度窗口。

一手资料

资料与版本边界复核日期:2026-08-22。工具行为可能演进,实施前以锁定版本对应的官方文档为准。

评论
分享

评论