三种主流策略
| 策略 | 例子 | 优点 | 缺点 |
|---|---|---|---|
| URL | /v1/users | 直观、易调试、可缓存 | 污染路径 |
| 请求头 | Accept: application/v1+json | URL 干净 | 不可见、难调试 |
| 无版本 | 只增不改 | 最简单 | 改语义就崩 |
关键不在选哪个
真正重要的是弃用流程:先在响应里返回 Deprecation 头,给老版本留够迁移期,再下线;同时保证向后兼容的加法(新字段可选)不破坏旧客户端。
两个坑
- 版本泛滥:每个小改动都开 v 版,维护成本爆炸;
- 不留过渡期:直接删接口等于让调用方半夜故障。
版本治理的落地机制
策略定下来只是开始,真正决定成败的是配套机制:
- 版本路由集中管理:把版本解析放在网关或统一中间件,业务代码不感知版本号,避免每个接口各写一套判断;
- 调用量可见:按版本打点统计请求量、错误率与调用方分布,下线前必须能回答“还有谁在用”;
- 弃用流程自动化:在响应头返回弃用时间(
Deprecation/Sunset),并在日志中对旧版本调用打标记,便于定向通知; - 契约测试兜底:为每个在用版本保留一组契约测试,防止重构时无意破坏旧版本;
- 文档与代码同源:版本说明由接口定义生成,避免文档写着 v2、实现已经到 v3。
把这五点做齐后,版本下线从“不敢动”变成一次常规发布;缺少任何一项,旧版本往往会长期滞留,最终拖垮维护成本。
与非破坏性演进的配合
减少版本数量最有效的办法,是让尽可能多的变更变成非破坏性的。
- 新增可选字段:优先以新增可选字段的方式扩展能力,而不是修改既有字段的含义。调用方忽略未知字段是应被明确要求的兼容规则。
- 保留已删除字段一段时间:字段下线应分两步:先停止返回但保留文档说明,观察一段时间确认无调用方依赖后再删除声明。
- 用默认值替代必填化:需要收紧校验时,先给出合理默认值让调用方有过渡期,再在下一个版本中改为必填。
- 枚举要有未知分支:新增枚举值会让未更新的调用方解析失败,因此调用方应被要求处理未知值,服务端也应避免删除已有枚举值。
- 变更走评审:把接口定义的改动纳入代码评审,明确标注是否兼容,能在源头拦住大部分破坏性变更。
当非破坏性变更成为默认做法时,版本升级的频率会自然下降,维护成本也随之降低,这比事后管理大量并行版本更省力。