API 版本化是什么
对外接口需要一套可演进的兼容策略:客户端可能几个月不升级,服务端却要持续迭代。做法主要有三类——路径版本(/v1/orders)直观但不便跨接口统一、请求头或媒体类型版本(Accept 带版本)让 URL 保持稳定、服务端内部按兼容规则演进而不显式升版本。核心原则是优先做兼容性扩展(加可选字段、加枚举值),只有删除字段、改语义、收窄校验这类破坏性变更才升版本,并为旧版本设定维护窗口与下线日期。
基本信息
| 路径版本 | 直观易调试、便于网关分流,缺点是版本散落在各路径 |
|---|---|
| 头/媒体类型版本 | URL 保持稳定,调试与缓存配置更复杂 |
| 兼容优先 | 新增可选字段与可忽略枚举值属兼容变更;删改语义才是破坏性变更 |
| 弃用流程 | 公告 → 观测调用方用量 → 灰度切线 → 下线并回收文档 |
| 配套要求 | 版本策略写入接口规范,变更评审时按规则判定是否升级 |
典型使用场景
- 对外开放平台:给第三方开发者提供稳定契约,用版本管理演进节奏
- 客户端长期不升级:移动端与嵌入式设备更新慢,需要并行维持旧版本
- 接口重构:字段结构调整无法兼容时,用新版本承接新调用方
- 多租户集成:不同租户迁移进度不同,按版本分批切换
- 网关治理:按版本维度统计流量与错误率,评估下线时机
- 内部服务契约:服务间接口同样需要兼容规则,避免全链路同时发布
变更类型与兼容性
| 变更 | 兼容性 | 做法 |
|---|---|---|
| 新增可选字段 | 兼容 | 客户端必须忽略未知字段,文档明确要求 |
| 新增枚举值 | 视客户端实现 | 文档声明需容忍未知值,客户端不得穷举报错 |
| 字段含义变更 | 破坏 | 新版本或新增字段名替代,旧字段冻结原语义 |
| 删除字段或收窄校验 | 破坏 | 先观测调用方用量,公告窗口后再灰度下线 |
| 调整错误码语义 | 破坏 | 沿用原码新增细分码,或在新版本中调整 |
演进与下线节奏
演进与下线节奏
# 1 记录调用方:按 appId 统计各版本调用量与最后调用时间
# 2 公告窗口:至少覆盖客户端的强制升级周期(移动端常按季度计)
# 3 灰度切线:先对新调用方默认返回新版本,旧调用方按 appId 保留
# 4 双写期:新旧版本同时可用,文档标注旧版本不再新增能力
# 5 下线前复检:确认零调用后再关闭路由,保留一段只读期用于回退
# 6 回收:删除旧版本文档与测试用例,避免后续维护成本叠加版本数量要控制:每个并行维护的旧版本都意味着额外的测试、文档与修复成本,通常建议同时维护的对外版本不超过两到三个。
「客户端忽略未知字段」必须写进接口规范并被测试覆盖:这条约定不落实,新增字段就会变成事实上的破坏性变更。