关于 api-versioning-strategy
为工程团队生成 API 版本策略文档,涵盖版本方案、生命周期、变更分类和弃用沟通。它先收集 API 类型、消费者及迁移约束等信息,再按上下文定制策略。
主要功能
- 01制定版本方案并说明理由
- 02定义版本生命周期与支持规则
- 03分类破坏性和非破坏性变更
- 04提供弃用通知与迁移指南模板
适用场景
- 01为新 API 建立版本管理规则
- 02规划旧版本弃用和消费者迁移
- 03评估 API 变更是否需要主版本升级
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mohitagw15856/ pm-claude-skills --skill api-versioning-strategy安装后在 Claude Code 中输入/api-versioning-strategy确认已加载。
详细介绍
API 版本控制策略
制定一份完整的 API 版本控制策略文档,为服务团队提供持久、一致的规则,以便在演进 API 的同时不破坏使用方。本文件涵盖版本控制方案的选择(及其理由)、从引入到停止服务的生命周期政策、精确的破坏性变更分类,以及团队弃用某个版本所需的所有沟通材料。工程师应能够将此文档交给新团队成员或外部使用方,让他们准确了解预期情况。
所需输入
如果尚未提供,请询问以下信息:
- API 类型 — REST、GraphQL 或 gRPC(每种类型的版本控制机制都不同)
- 当前版本控制方式 — URL 路径(
/v1/)、请求标头、查询参数或无;如果没有,文档将从头开始编写 - 现有版本数量和活跃使用方数量 — 用于确定生命周期政策的规模和迁移范围
- 弃用时间线限制 — 任何硬性截止日期(合同 SLA、合规窗口、年度发布周期)
- 使用方类型 — 仅内部团队、外部合作伙伴、公共 API 或混合(会影响沟通渠道的选择)
如果缺少任何输入,请先询问,再编写文档。对于 GraphQL,请注意其版本控制方式有很大不同(通过演进架构而非版本控制),并据此调整方案部分。
输出格式
API 版本控制策略:[服务名称]
负责人:[团队名称]
API 类型:[REST / GraphQL / gRPC]
**文档版本:**1.0
上次审核:[日期]
下次审核:[日期 + 6 个月]
1. 版本控制方案
已选方案:[URL 路径 / 请求标头 / 查询参数]
| 方案 | 示例 | 优点 | 缺点 | 结论 |
|---|---|---|---|---|
| URL 路径 | /v2/orders | 在日志和书签中清晰可见;路由简单直接 | 违背严格的 REST 资源标识原则;使 URL 空间变得杂乱 | 推荐用于面向公众的 REST API |
Accept 标头 | Accept: application/vnd.[service].v2+json | 保持 URL 简洁;符合内容协商规范 | 在浏览器中较难测试;在日志中不够明显 | 推荐用于客户端受控的内部 API |
| 查询参数 | /orders?version=2 | 无需重构 URL 即可轻松改造 | 客户端代码中常会遗漏;存在缓存键方面的复杂性 | 仅适用于已上线且以读取为主的 API |
| GraphQL 架构演进 | 字段弃用 + @deprecated 指令 | 添加变更无需版本控制 | 需要严谨的架构设计 | 推荐用于 GraphQL API |
选择[所选方案]的理由:[用一段话说明该方案为何适合所提供的 API 类型、使用方类型和运营环境。引用具体输入,例如:“由于此 API 的外部合作伙伴通过生成的客户端进行集成,URL 路径版本控制能够提供最可预测的路由行为,并消除标头协商的复杂性。”]
版本格式
[Base URL]/v{MAJOR}/{resource}
Examples:
https://api.[company].com/v1/orders
https://api.[company].com/v2/orders/{id}/items
Version identifier: integer only (v1, v2, v3)
No minor versions in the URL — minor/patch changes are non-breaking and deployed continuously.
2. 版本生命周期政策
生命周期阶段
STABLE ──────────────────────────────────────────────────►
│
├─ STABLE Active development, full SLA, new consumers allowed
│
├─ DEPRECATED Announced, timeline posted, migration docs live.
│ New consumers blocked. Existing consumers receive warnings.
│
├─ SUNSET Requests return HTTP 410 Gone + migration pointer.
│ 30-day window before routing is removed.
│
└─ RETIRED Routing removed, docs archived, no traffic accepted.
| 阶段 | 时长 | SLA 是否适用 | 是否允许新使用方 | 所需操作 |
|---|---|---|---|---|
| 稳定 | 直到被取代 | 是 — 完整适用 | 是 | 无 |
| 已弃用 | [12 个月 / 根据限制调整] | 是 — 可接受降级 | 否 | 在停止服务日期前迁移 |
| 停止服务 | 30 天窗口期 | 仅尽力而为 | 否 | 立即迁移 |
| 已退役 | 永久 | 不适用 | 否 | — |
**最短稳定期:**宣布弃用前,某个版本必须至少保持稳定 [6 / 12] 个月。
**同时存在的版本上限:**在任何时候,处于稳定或已弃用状态的版本不得超过 [2] 个。发布 v3 时,必须在同一公告中承诺 v1 的停止服务日期。
3. 破坏性与非破坏性变更分类
每次 API 变更前,都要应用此表。如果变更标记为破坏性,则需要发布新的主版本。如有疑问,默认归为破坏性变更。
| 变更类型 | 具体示例 | 分类 | 理由 |
|---|---|---|---|
| 删除响应字段 | 从响应中删除 order.legacy_id | 破坏性 | 读取此字段的客户端会触发空指针错误或运行失败 |
| 重命名字段 | user_name → username | 破坏性 | 引用旧名称的客户端会收到 null |
| 更改字段类型 | "amount": "10.00" → "amount": 10.00 | 破坏性 | 反序列化时会发生类型不匹配 |
| 将可选字段改为必填 | POST 请求体中的 email 设为必填 | 破坏性 | 省略此字段的现有调用方会收到 400 |
| 删除端点 | 删除 DELETE /v1/widgets/{id} | 破坏性 | 现有调用方会收到 404 |
| 更改 HTTP 方法 | GET /search → POST /search | 破坏性 | 已收藏或缓存的 GET 调用会失败 |
| 更改身份验证方案 | API 密钥 → OAuth2 | 破坏性 | 所有客户端都必须重新进行身份验证 |
| 调整错误响应结构 | 错误 JSON 架构已更改 | 破坏性 | 错误处理代码会错误解析响应 |
| 扩展枚举值(响应) | 返回新的 status: "on_hold" 值 | 破坏性 | 没有 default 分支的 switch 语句会遗漏处理 |
| 更改分页默认值 | page_size 默认值从 20 改为 50 | 破坏性 | 响应长度会出现意外变化 |
| 收紧输入验证 | 最大长度从 100 改为 50 | 破坏性 | 之前有效的输入现在会被拒绝 |
| 在响应中添加新的可选字段 | 添加 order.tax_breakdown | 非破坏性 | 根据规范,客户端会忽略未知字段 |
| 添加新的可选请求参数 | 添加 ?include_archived=true | 非破坏性 | 现有客户端会忽略此参数 |
| 添加新端点 | GET /v1/orders/{id}/audit | 非破坏性 | 没有现有客户端引用此端点 |
| 放宽输入验证 | 最小长度从 10 改为 5 | 非破坏性 | 现有有效输入仍然有效 |
| 提升性能或降低延迟 | 响应时间缩短 | 非破坏性 | — |
| 添加新的枚举值(仅请求) | 接受新的 type: "express" | 非破坏性 | 现有值仍然可接受 |
4. 弃用流程
弃用分步检查清单
- T-0(决策日): 工程负责人批准弃用。确认新版本为 Stable。确定日落日期。
- T-0: 更新 API 文档——在所有 v[N] 端点页面添加弃用横幅。
- T-0: 在所有 v[N] 响应中添加
Deprecation和Sunset响应标头(格式见下文)。 - T-0: 在 API 网关和开发者门户中停止为 v[N] 接入新的使用方。
- T-0: 向所有已注册的使用方发送初始弃用通知(模板见第 5 节)。
- T-0: 在工程待办事项中创建跟踪问题,将所有已知使用方及其迁移状态关联起来。
- T 前 30 天: 向仍在发送 v[N] 流量的所有使用方发送 30 天预警。
- T 前 7 天: 发送最终预警。如果使用方流量 > 100 req/day,直接向其工程负责人升级处理。
- 日落日期: 将 v[N] 路由切换为返回
HTTP 410 Gone,并在响应正文中指向迁移指南。 - T 后 30 天: 删除路由规则。归档文档。关闭跟踪问题。
弃用响应标头
HTTP/1.1 200 OK
Deprecation: true
Sunset: Sat, 01 Jan 2027 00:00:00 GMT
Link: <https://docs.[company].com/api/migration/v1-to-v2>; rel="successor-version"
日落响应正文
HTTP/1.1 410 Gone
Content-Type: application/json
{
"error": "api_version_sunset",
"message": "API v1 was sunset on 2027-01-01. Please migrate to v2.",
"migration_guide": "https://docs.[company].com/api/migration/v1-to-v2",
"support": "api-support@[company].com"
}
5. 客户端沟通模板
初始弃用通知
Subject: [Action Required] [Service Name] API v[N] Deprecation — Sunset [Date]
Hi [Team / Partner Name],
We are deprecating [Service Name] API v[N], effective [Sunset Date].
What this means for you:
- v[N] continues to work normally until [Sunset Date]
- After [Sunset Date], all v[N] requests return HTTP 410 Gone
- v[N+1] is available today and fully stable
Your current usage: approximately [X] requests/day as of [Date].
Estimated migration effort: [Small: < 1 day | Medium: 1–3 days | Large: 3–10 days]
Migration resources:
Migration guide: [URL]
Changelog: [URL]
Office hours: [Date/Time/Link]
Support: [Slack channel or email]
Key dates:
[Date] Deprecation announced (today)
[Date] New consumer onboarding blocked for v[N]
[Date] 30-day warning sent to remaining consumers
[Sunset Date] v[N] returns 410 Gone
Reply to this message or contact us at [channel] with questions.
[Your Name], [Team Name]
30 天预警
Subject: [30 Days Remaining] [Service Name] API v[N] sunsets [Date]
Hi [Team / Partner Name],
[Service Name] API v[N] sunsets in 30 days on [Date].
Your current v[N] traffic: [X] requests/day — migration is not yet complete.
If you have a technical blocker requiring an extension, contact us before
[Date minus 14 days]. Extensions require a documented blocker and a committed
migration completion date.
Migration guide: [URL] | Support: [channel]
6. 迁移指南模板
每次版本迁移都要发布一份迁移指南,路径为 docs.[company].com/api/migration/v[N]-to-v[N+1]。
# Migration Guide: v[N] → v[N+1]
**Estimated effort:** [Small: < 1 day | Medium: 1–3 days | Large: 3–10 days]
**Breaking changes in this guide:** [count]
## Quick Start
Update your base URL:
Before: https://api.[company].com/v[N]/
After: https://api.[company].com/v[N+1]/
## Breaking Changes
### 1. [Field Rename: user_name → username]
**Affected endpoints:** `GET /users/{id}`, `POST /users`
Before (v[N]):
{ "user_name": "alice" }
After (v[N+1]):
{ "username": "alice" }
Migration: Replace all references to `user_name` with `username` in request
builders and response parsers.
### 2. [Next breaking change — repeat structure]
## New Capabilities in v[N+1]
| Feature | Description | Docs |
|---------|-------------|------|
| [Feature name] | [Brief description] | [Link] |
## SDK Upgrade Reference
| Language | Package | v[N+1] Version | Install Command |
|----------|---------|----------------|-----------------|
| Python | `[company]-sdk` | `2.0.0` | `pip install [company]-sdk==2.0.0` |
| Node.js | `@[company]/sdk` | `2.0.0` | `npm install @[company]/[email protected]` |
| Go | `github.com/[company]/sdk-go` | `v2.0.0` | `go get github.com/[company]/sdk-go/v2` |
| Java | `com.[company]:sdk` | `2.0.0` | Update pom.xml / build.gradle |
## Migration Validation Checklist
- [ ] Base URL updated to v[N+1]
- [ ] All renamed fields updated in request serializers
- [ ] All renamed fields updated in response deserializers
- [ ] Error-handling code updated for new error shape
- [ ] Integration tests passing against v[N+1] in staging
- [ ] Load test completed against v[N+1] — latency within acceptable range
- [ ] Rollback plan documented if issues arise post-cutover
7. 特定版本的文档
- 为每个稳定版和弃用版分别维护文档页面。
- 弃用版文档需持续显示横幅:“此版本已弃用。日落日期:[Date]。[迁移到 v[N+1]]。”
- OpenAPI 规范、Protobuf 定义或 GraphQL 架构需按版本添加标签,并在仓库的
/api/v[N]/下归档。 - 根目录下的 CHANGELOG.md 按版本记录所有不兼容和兼容变更,不得将其埋在提交历史中。
8. SDK 版本对齐
| API 版本 | SDK 主版本 | SDK 正式发布日 | SDK 生命周期终止日 |
|---|---|---|---|
| v[1] | 1.x | [Date] | [API Sunset + 90 days] |
| v[2] | 2.x | [Date] | Active |
- SDK 主版本与 API 主版本保持 1:1 对齐。
- SDK 次版本跟进不兼容的 API 新增功能。
- SDK 生命周期终止日期比 API 日落日期晚 90 天,为使用方留出更多时间。
- 底层 API 版本弃用时,SDK 会在运行时输出弃用警告日志。
策略由 [Team Name] 编写 — 问题请联系 [Slack channel or email]
反模式
- 不要将扩展枚举(新增响应值)归类为兼容变更——收到意外枚举值时,使用穷举 switch 语句的客户端会出错
- 未确认最大使用方能够按期完成之前,不要设置日落日期——若日落日期迫使使用方错过法律期限,他们会忽略通知或上报问题
- 不要同时维护超过两个稳定版/弃用版——每增加一个受支持版本,维护负担和使用方困惑都会加倍
- 不要仅靠“监控流量”来判断所有使用方是否都已迁移——应明确跟踪各使用方的迁移完成情况
- 不要跳过迁移指南——没有估算工作量的分步指南,使用方就会无限期推迟迁移
质量检查
- 版本方案建议包含与所提供的 API 类型和使用方类型直接相关的明确理由,而不是泛泛而谈
- 不兼容变更表至少涵盖:移除字段、重命名字段、更改类型、将可选字段改为必填、移除端点、扩展枚举以及更改默认值
- 弃用时间线的时长需填写具体数值,不得保留为抽象占位符
- 三种沟通材料均已提供:初始弃用通知、30 天警告和迁移指南模板
- 日落响应头(
Deprecation、Sunset、Link)使用正确的 RFC 日期格式和真实 URL 结构 - SDK 版本对齐表已提供,并明确列出 SDK 主版本与 API 主版本的对应关系
- 明确说明同时受支持版本数量的上限,并给出具体数字