做开发这些年,最怕的不是写新功能,而是接到通知说:老接口要改,但旧系统还得跑。上周就碰上这么一出,公司内部订单系统升级,API 要加字段,可仓库那边还在用两年前的对接程序,一更新,直接报错崩溃。
问题从哪来?
说白了,就是接口文档没做好兼容性处理。新版返回的数据里多了一个 status_detail 字段,类型是对象,而老客户端解析时没做容错,遇到不认识的字段直接抛异常。这其实挺典型的——我们总以为调用方会按最新文档来,可现实是,很多系统上线后几年都不动一次,没人敢轻易升级。
怎么解决?
第一反应是让仓库系统升级,结果一问,原开发离职了,文档不全,对方也不敢动。那就只能在我们这端想办法。最后决定走“渐进式兼容”路线:接口保持原有字段不变,新增字段设为可选,并在文档里明确标注版本号和兼容策略。
比如原来返回:
{
"order_id": "12345",
"status": "shipped"
}现在改成:
{
"order_id": "12345",
"status": "shipped",
"status_detail": {
"code": 200,
"desc": "已发货"
}
}关键点是,老系统读到这个数据时,忽略 status_detail 就行,只要不影响主流程,就能继续跑。
文档怎么写才靠谱?
光改代码不够,文档得跟上。我们在 Swagger 里加了三个东西:一是版本标签,标清楚 v1.1 新增字段;二是兼容说明,写明“旧客户端可安全忽略新增字段”;三是示例分组,分别列出兼容模式和最新模式的返回样例。
有次开会,产品问为啥不干脆删了旧字段?我说就像你家路由器换了新的,但爷爷的收音机还连着老Wi-Fi,你能一刀断网吗?软件世界也一样,过渡期得留条活路。
自动化测试补了一刀
后来我们加了回归测试脚本,每次发版都用老版本的解析器跑一遍接口响应,确保不会炸。这招是从一个电商朋友那学来的,他们叫“影子校验”,听着玄乎,其实就是拿旧逻辑验证新输出。
接口变更是常态,但别让变更变成事故。把兼容性当成接口设计的一部分,比事后救火强得多。