← [ BACK_TO_NOTES ]

API版本管理

API 契约的版本选择、兼容判断、迁移与废弃通知,区分版本标识和真实兼容性。

#backend #concept #evergreen

[!info] related notes

API 版本管理

API 版本管理让客户端明确依赖哪个契约,并为不兼容变更提供迁移路径。写上 /v2 只是标识,不能自动保证旧客户端兼容。

先判断是不是破坏性变更

例如把 { "name": "John Doe" } 改成 { "firstName": "John", "lastName": "Doe" },会影响依赖 name 的客户端,不意味着所有客户端必然崩溃。

常见不兼容变化包括删除或重命名字段、改变类型或单位、收紧请求约束,以及改变错误码、分页、排序、授权和幂等语义。

新增可选响应字段通常较容易兼容,但严格解码器可能拒绝未知字段;新增 enum 值可能破坏穷尽分支。新增必填请求字段通常会影响旧客户端。“新增”或“修 bug”本身不能证明兼容,需检查消费者行为。

版本选择方式

方式示例主要取舍
URL 路径/api/v1/users路由、日志与缓存区分直观,客户端 URL 随版本变化
查询参数/api/users?version=1保留路径;需定义缺省版本并确保缓存键包含版本参数
自定义请求头API-Version: 1URL 不变;网关与缓存需按该头区分响应,浏览器跨源可能触发预检
媒体类型协商Accept: application/vnd.example.user.v1+json用 HTTP 内容协商表达响应表示;需正确解析媒体范围、参数和优先级
子域名v1.api.example.com可分开运维,但增加域名、证书与跨源配置成本

Accept 表示客户端接受什么响应;请求中的 Content-Type 描述发送的请求体。两者不能互换,也不应把 Media Type 与 Header 写成互不相干的版本机制。

响应随请求头变化时,应正确设置例如 Vary: Accept 或 Vary: API-Version,并核对网关实际缓存策略。地址栏不方便设置任意请求头,不代表浏览器的 Fetch 无法选择版本。

路由与默认值

/api/v1/users → v1 契约处理
/api/v2/users → v2 契约处理
不支持的版本 → 明确的错误响应
未指定版本 → 文档规定的固定默认值,或要求显式选择

不要默默把未知版本按 v1 解析,也不要把默认契约自动漂移到“最新版本”。用 Header 或查询参数选择版本时,需处理缺失、类型不符和不支持值,避免请求无响应。

API 主版本可与实现的 SemVer 发布号分开。采用日期版本或其他标识也可行;没有所有 API 都必须只用主版本号的规则。

历史 DailyUse 方案

旧记录推荐路径 /api/v1/users、/api/v1/sync/push、/api/v1/devices,以及 Express 的 v1/v2 router 分组、对未变化的 sync 路由复用实现。

这是设计建议,不是当前 DailyUse 仓库或服务的部署证据。原 api.dailyuse.app/v1、/v2、/v3 与 2025-12-31 停用日期也只是旧方案示例,不能推定真实域名、版本或停服安排。

复用路由前需验证权限、输入、输出、错误和副作用仍满足两个版本的契约;仅因为处理函数相同不等于兼容。

数据适配与发布

  • 适配器应保留旧契约语义;用空格拆分全名不能可靠恢复姓和名,这种转换可能不可逆。
  • 新旧 API 共用数据库时,还要维护读写兼容窗口。应用回滚不等于数据结构可回滚,见 database-schema-migration-release-compatibility。
  • 同一 API 契约内灰度新实现,与随机把旧契约请求转到不兼容 v2 是两件事。旧客户端不能仅按流量比例被强制送入新格式。
  • 并行支持几个版本、保留多久,要结合客户端升级周期、使用数据和维护成本决定,不固定要求“两版、六个月”。

废弃通知

RFC 9745 中 Deprecation 使用 Structured Field Date,不是布尔字符串 true。Sunset 使用 HTTP 日期,表示预期停止响应的时间;废弃本身不等于立即停服。

下面是历史日期的协议格式示例,不代表实际服务日程:

Deprecation: @1688169599
Sunset: Sun, 30 Jun 2024 23:59:59 GMT
Link: <https://api.example.com/migration>; rel="deprecation"; type="text/html"

客户端按字段标准解析,不用 Deprecation === 'true' 判断。需要浏览器跨源读取时,服务端还应通过 Access-Control-Expose-Headers 暴露相应头。迁移说明应明确范围、替代方式与停用日期;Sunset 不应早于废弃日期。

正式移除旧资源时可以按 API 约定返回 410 等明确结果,不能把所有未知路由都误报成“版本已停用”。

验证重点

  • 用真实消费者样例检查旧客户端 + 新服务、新客户端 + 过渡服务。
  • 测试字段、类型、未知 enum、错误、分页、权限与写入副作用,不只断言几个字段存在。
  • 检查版本选择、缺省与不支持值,防止缓存把不同版本响应混用。
  • 检查废弃头格式、跨源可见性和迁移文档。
  • 客户端应用版本与 API 版本分开记录;需要比较应用 SemVer 时按版本规则解析,不能按字符串大小判断(如 1.10.0 与 1.9.0)。

参考

创建于 2025/12/8 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本