导致应用崩溃的 9 个 API 变更
“我们没有破坏任何东西,我们只是清理了响应。”
这些话往往会导致崩溃。移动应用失效。合作伙伴的集成返回乱码。你改变了他人所依赖的数据结构。
危险的变更往往看起来像是“整理”。它们能通过代码审查和测试,但破坏却发生在你看不到的代码中。
以下是九种看似安全实则不然的变更。
重命名字段 为了保持一致性将
userId改为user_id会导致客户端崩溃。重命名本质上是“删除”加“新增”。其中的删除操作会破坏现有功能。 安全做法:添加新字段。保留旧字段。将其标记为弃用(Deprecate)。在很久之后再将其移除。将字段设为可选 字段以前一直存在,现在有时为
null。客户端代码在尝试处理它时会发生崩溃。 安全做法:将“始终存在”视为一种承诺。如果一个字段变为可选,请使用新版本。移除未使用的字段 你无法预知消费者是如何使用你的数据的。“未使用”仅仅意味着你没有在使用它。 安全做法:在移除任何内容之前,先在生产环境中测量字段的使用情况。
收窄输入类型 将字符串改为枚举,或将数字改为整数,都会导致请求失败。放宽输入范围是安全的,而收窄输入则是破坏性变更。 安全做法:只放宽你接受的输入。收紧输入需要使用新版本。
修改默认值 将默认值从
false改为true会在不报错的情况下改变行为。这会悄无声息地破坏逻辑。 安全做法:将默认值的变更视为破坏性变更。添加必填字段 添加
tenantId并将其设为必填,会破坏所有现有的客户端。它们会收到 400 错误。 安全做法:新字段必须是可选的,或者使用新版本。修改错误格式 将 400 错误改为 422 错误,或者修改错误主体(error body),都会破坏错误处理代码。 安全做法:错误格式是一种契约。像对待其他内容一样对其进行版本管理。
修改枚举值 将 "active" 重命名为 "ACTIVE" 会导致客户端崩溃。移除某个值会破坏具有严格逻辑的客户端。 安全做法:枚举值是永久性的。谨慎添加。在没有发布大版本的情况下,绝不要重命名或移除它们。
改变数据含义 将日期从 Unix 秒改为 ISO-8601,或者将分页方式从 offset 改为 cursor,会破坏一切。Schema 对比(schema diff)甚至可能检测不到这些变化。 安全做法:明确固定格式。对比实际的有效负载(payloads),而不仅仅是规范(spec)。
不要凭感觉。在 CI 中将每一次变更都与生产环境的契约进行对比。人可能会忽略重命名的字段,但 diff 工具不会。
来源:https://dev.to/deepaksatyam/9-api-changes-that-look-backwards-compatible-but-arent-1bk0