接口稳定性与兼容性设计
对外接口一旦发布就是承诺:调用方按它写代码、按它做集成,你的内部重构自由建立在不破坏它的前提上。兼容策略的原则是只增不删——新增可选字段、给新参数默认值、保留旧字段语义;确实需要破坏时走新版本并行加废弃周期。设计边界输入时可参考 Postel 法则:发送端保守、接收端宽容。
基本信息
| 兼容策略 | 只增不删、弃用标记、新旧版本并行 |
|---|---|
| Postel 法则 | 接收端宽容、发送端保守 |
| 工具 | SemVer 语义化版本、废弃注解与文档标记 |
| 废弃周期 | 标记、告警、统计调用量、下线公告 |
兼容手法
- 新增而非修改:加字段、加可选参数,旧调用行为保持不变
- 改变字段语义时另起新字段,把旧字段标记为废弃并给出迁移说明
- 接收端对未知字段宽容忽略,避免上游加字段就导致解析失败
- 枚举新增取值时提前约定未知值处理策略,防止旧客户端崩溃
- 下线前统计调用量,确认没有活跃调用方再执行
- 把兼容承诺写进接口文档与版本号规则,避免口头约定
兼容改造示例
兼容改造示例
// 破坏性变更:缩小合法输入范围,或改变已有字段的含义
// 兼容变更:新增可选字段并给出默认行为
{"timeout_ms": 3000} // 旧调用,语义不变
{"timeout_ms": 3000, "retry": 2} // 新调用,新增可选字段
// 反例:把 timeout_ms 的含义从「总超时」改成「单次超时」
// 旧调用方不知道语义已变,线上行为静默改变变更类型与兼容性
| 变更 | 是否兼容 | 建议做法 |
|---|---|---|
| 新增可选字段 | 兼容 | 给默认值,旧调用不受影响 |
| 新增必填字段 | 不兼容 | 改为可选或走新版本 |
| 删除字段 | 不兼容 | 先废弃并观察调用量 |
| 收紧取值范围 | 不兼容 | 保留宽范围,另加校验接口 |
| 改变字段语义 | 不兼容 | 另起新字段,旧字段并存 |
| 新增枚举取值 | 视情况 | 约定未知值处理策略 |
语义化版本的约定是:主版本号变更表示不兼容改动,次版本号表示向后兼容的新增,修订号表示兼容的问题修复。它只有在团队真的按语义发布时才有意义,否则版本号只是装饰。
接收端宽容不等于吞掉错误:把无法解析的输入当作空值处理,坏数据会被静默接受并写入下游。宽容的对象是「可忽略的额外信息」,对于必填字段缺失仍应明确失败。