API版本控制Skill api-versioning

API版本控制技能专注于设计和实施API的版本化策略,确保API的演化和兼容性,处理破坏性变更,优雅地弃用旧版本。关键词包括API版本化、破坏性变更、弃用管理、RESTful API、微服务、软件架构、后端开发、API网关。

架构设计 0 次安装 0 次浏览 更新于 3/11/2026

name: api-versioning description: 用于规划API版本化策略、处理破坏性变更或管理API弃用。涵盖URL、头部和查询参数版本化方法。 allowed-tools: Read, Glob, Grep

API 版本化

版本化API的策略、管理破坏性变更以及优雅地弃用旧版本。

何时使用此技能

  • 选择API版本化策略
  • 规划破坏性变更
  • 弃用API版本
  • 管理多个API版本
  • 为API演进设计

为什么版本化API?

API是与客户的合约。
破坏性变更会破坏客户。

没有版本化:
- 更改字段名称 → 所有客户中断
- 删除端点 → 所有客户中断
- 更改行为 → 意外的客户行为

有版本化:
- 旧客户使用旧版本
- 新客户使用新版本
- 可能逐步迁移

版本化策略

URL路径版本化

https://api.example.com/v1/users
https://api.example.com/v2/users

优点:
- 清晰明确
- 易于理解
- 易于路由
- 易于缓存

缺点:
- 版本嵌入客户端代码
- 同一资源多个URL
- 非真正RESTful(URL应标识资源)

头部版本化

GET /users
Accept: application/vnd.example.v1+json

或自定义头部:
GET /users
API-Version: 1

优点:
- 干净的URL
- 更RESTful
- 版本与资源分离

缺点:
- 从URL隐藏
- 在浏览器中难以测试
- 需要头部支持

查询参数版本化

GET /users?version=1
GET /users?api-version=2023-01-01

优点:
- 易于添加
- 可选(可默认)
- 易于测试

缺点:
- 可能被遗忘
- 污染查询字符串
- 缓存复杂性

内容协商

Accept: application/vnd.example+json; version=1

优点:
- 标准HTTP机制
- 灵活

缺点:
- 实现复杂
- 难以发现

策略比较

策略 可见性 实现难度 缓存 推荐
URL路径 容易 容易 最佳用于公共API
头部 中等 中等 良好用于内部API
查询参数 中等 容易 复杂 良好用于简单情况
内容协商 复杂 中等 很少使用

版本化方案

整数版本

v1, v2, v3

优点:简单,明确主要变更
缺点:粗粒度

最佳用于:公共API,破坏性变更不频繁

语义版本化

v1.2.3(主要.次要.补丁)

主要:破坏性变更
次要:新功能(向后兼容)
补丁:错误修复

优点:细粒度,可预测
缺点:更复杂

最佳用于:库,SDK

基于日期的版本化

2023-01-15, 2023-06-01

优点:清晰版本当前时间
缺点:不指示变更幅度

最佳用于:频繁变化的API(Stripe,GitHub)

示例(Stripe):
Stripe-Version: 2023-10-16

什么需要新版本?

破坏性变更(新主要版本)

总是破坏性:
- 删除端点
- 删除字段
- 更改字段类型
- 更改字段含义
- 重命名字段
- 添加必需字段
- 更改认证
- 更改错误格式

非破坏性变更(不需要版本)

安全变更:
- 添加新端点
- 添加可选字段
- 添加新枚举值
- 添加可选参数
- 放宽验证
- 添加新错误代码

版本管理

运行多个版本

选项1:独立代码库
/v1/* → v1服务
/v2/* → v2服务

优点:完全隔离
缺点:重复,维护负担

选项2:共享代码库分支
if (version == 1) {
  return formatV1(data);
} else {
  return formatV2(data);
}

优点:单一代码库
缺点:代码复杂性增长

选项3:转换层
内部模型 → 版本特定转换器 → 响应

优点:清晰分离
缺点:需要转换代码

版本路由

API网关模式:

客户端 → 网关 → 按版本路由 → 服务

网关职责:
- 从URL/头部解析版本
- 路由到适当后端
- 如果需要转换
- 处理默认值

弃用策略

生命周期阶段

1. 当前:活跃开发
2. 维护:仅错误修复
3. 弃用:无变更,宣布日落
4. 日落:移除

时间线示例:
v1:当前(12个月)
v1:v2启动时维护(6个月)
v1:弃用(6个月)
v1:日落

弃用通信

头部:
Deprecation: true
Sunset: Sat, 1 Jul 2024 00:00:00 GMT
Link: <https://api.example.com/v2/docs>; rel="successor-version"

响应体:
{
  "data": {...},
  "_deprecation": {
    "message": "此API版本已弃用",
    "sunset": "2024-07-01",
    "successor": "https://api.example.com/v2"
  }
}

迁移支持

提供:
1. 迁移指南记录所有变更
2. 旧 → 新端点映射
3. 常见操作代码示例
4. SDK更新与兼容层
5. 沙盒环境用于测试

最佳实践

默认版本

选项:
1. 要求显式版本(推荐用于公共API)
2. 默认最新(稳定性危险)
3. 默认最旧支持(保守)

推荐:要求版本,缺失时失败

响应中的版本

在响应中包含版本信息:

{
  "data": {...},
  "_meta": {
    "api_version": "v2",
    "deprecated": false
  }
}

优雅降级

当版本未知时:
1. 返回错误并支持版本列表
2. 重定向到文档
3. 返回最新版本并警告

HTTP 400 错误请求
{
  "error": "未知API版本",
  "supported_versions": ["v1", "v2"],
  "documentation": "https://docs.example.com/api"
}

测试多个版本

测试矩阵:
- 所有支持版本
- 破坏性变更边界
- 弃用警告
- 日落行为

自动化测试:
- 每版本合同测试
- 向后兼容性测试
- 迁移路径测试

真实世界示例

Stripe

基于日期:2023-10-16
头部:Stripe-Version
默认:账户的API版本
回滚:可固定到旧版本
升级:在仪表板预览

GitHub

基于日期:2022-11-28
头部:X-GitHub-Api-Version
默认:最新
预览功能:Accept头部

Google

URL路径:/v1/, /v2/
每版本发现文档
长弃用周期(年)

Twilio

基于日期:2010-04-01
URL路径包含日期
非常长的支持窗口

反模式

1. 过多版本
   → 合并,设置弃用计划

2. 次要版本中的破坏性变更
   → 严格遵循语义版本化

3. 无弃用警告
   → 始终在破坏前沟通

4. 即时日落
   → 给客户时间迁移(最少6-12个月)

5. 每端点版本
   → 保持所有端点每版本同步

相关技能

  • api-design-fundamentals - API设计模式
  • idempotency-patterns - 安全API操作
  • quality-attributes-taxonomy - 可维护性属性