API 版本管理 #

为什么需要版本管理? #

API 版本管理是 API 设计中至关重要的一环,它确保 API 在演进过程中保持向后兼容,同时允许引入新功能和改进。

text
┌─────────────────────────────────────────────────────────────┐
│                    版本管理的必要性                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  问题场景:                                                  │
│                                                             │
│  1. API 需要变更                                            │
│     - 添加新功能                                            │
│     - 修改数据结构                                          │
│     - 废弃旧接口                                            │
│                                                             │
│  2. 客户端兼容性                                            │
│     - 旧客户端仍在使用                                      │
│     - 不能强制所有客户端同时升级                            │
│     - 需要过渡期                                            │
│                                                             │
│  3. 风险控制                                                │
│     - 新版本可能有 bug                                      │
│     - 需要灰度发布                                          │
│     - 需要回滚能力                                          │
│                                                             │
│  解决方案:版本管理                                          │
│  ✅ 多版本共存                                              │
│  ✅ 平滑过渡                                                │
│  ✅ 风险可控                                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

版本号规范 #

语义化版本 #

text
┌─────────────────────────────────────────────────────────────┐
│                    语义化版本号                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  格式:MAJOR.MINOR.PATCH                                    │
│                                                             │
│  示例:2.1.3                                                │
│        │ │ │                                                │
│        │ │ └── PATCH:修复 bug,向后兼容                    │
│        │ └─── MINOR:新增功能,向后兼容                     │
│        └───── MAJOR:重大变更,不兼容                       │
│                                                             │
│  API 版本简化:                                              │
│  通常只使用 MAJOR 版本号                                    │
│  /v1/users                                                  │
│  /v2/users                                                  │
│                                                             │
│  原因:                                                      │
│  - MINOR 和 PATCH 版本向后兼容                              │
│  - 客户端无需感知小版本变更                                 │
│  - 简化版本管理                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

版本变更规则 #

text
┌─────────────────────────────────────────────────────────────┐
│                    版本变更规则                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  需要升级主版本号(Breaking Changes):                      │
│  ─────────────────────────────────────────────              │
│  - 删除端点                                                 │
│  - 重命名端点                                               │
│  - 修改请求/响应结构                                        │
│  - 修改必填字段                                             │
│  - 修改认证方式                                             │
│                                                             │
│  不需要升级主版本号(Non-Breaking Changes):                │
│  ─────────────────────────────────────────────              │
│  - 新增端点                                                 │
│  - 新增可选字段                                             │
│  - 新增查询参数                                             │
│  - 修复 bug                                                 │
│  - 性能优化                                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

版本管理策略 #

策略一:URL 路径版本(推荐) #

text
┌─────────────────────────────────────────────────────────────┐
│                    URL 路径版本                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  格式:/v{version}/resource                                 │
│                                                             │
│  示例:                                                      │
│  GET /v1/users                                              │
│  GET /v2/users                                              │
│  GET /v1/users/123                                          │
│  GET /v2/users/123                                          │
│                                                             │
│  优点:                                                      │
│  ✅ 简单直观,易于理解                                      │
│  ✅ 易于缓存(URL 不同)                                    │
│  ✅ 易于测试和调试                                          │
│  ✅ 浏览器可直接访问                                        │
│                                                             │
│  缺点:                                                      │
│  ❌ URL 变化                                                │
│  ❌ 需要维护多个路由                                        │
│                                                             │
│  实现示例:                                                  │
│  // Express.js                                               │
│  app.use('/v1', v1Router);                                  │
│  app.use('/v2', v2Router);                                  │
│                                                             │
│  // Nginx                                                    │
│  location /v1/ {                                            │
│    proxy_pass http://api-v1/;                               │
│  }                                                          │
│  location /v2/ {                                            │
│    proxy_pass http://api-v2/;                               │
│  }                                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

策略二:Header 版本 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Header 版本                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  方式一:自定义 Header                                       │
│  GET /users HTTP/1.1                                        │
│  Host: api.example.com                                      │
│  X-API-Version: 2                                           │
│                                                             │
│  方式二:Accept Header                                       │
│  GET /users HTTP/1.1                                        │
│  Host: api.example.com                                      │
│  Accept: application/vnd.myapi.v2+json                      │
│                                                             │
│  优点:                                                      │
│  ✅ URL 不变                                                │
│  ✅ 更符合 REST 原则                                        │
│  ✅ 支持内容协商                                            │
│                                                             │
│  缺点:                                                      │
│  ❌ 不够直观                                                │
│  ❌ 浏览器直接访问困难                                      │
│  ❌ 缓存配置复杂                                            │
│                                                             │
│  实现示例:                                                  │
│  // Express.js 中间件                                        │
│  app.use((req, res, next) => {                              │
│    const version = req.headers['x-api-version'] || '1';     │
│    req.version = version;                                   │
│    next();                                                  │
│  });                                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

策略三:查询参数版本 #

text
┌─────────────────────────────────────────────────────────────┐
│                    查询参数版本                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  格式:/resource?version={version}                          │
│                                                             │
│  示例:                                                      │
│  GET /users?version=1                                       │
│  GET /users?version=2                                       │
│  GET /users/123?version=1                                   │
│                                                             │
│  优点:                                                      │
│  ✅ URL 路径不变                                            │
│  ✅ 简单易用                                                │
│  ✅ 可选参数,默认使用最新版本                              │
│                                                             │
│  缺点:                                                      │
│  ❌ 参数可能被忽略                                          │
│  ❌ 与其他查询参数混淆                                      │
│  ❌ 缓存策略复杂                                            │
│                                                             │
│  实现示例:                                                  │
│  // Express.js                                               │
│  app.get('/users', (req, res) => {                          │
│    const version = req.query.version || '1';                │
│    // 根据版本处理请求                                      │
│  });                                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

策略四:子域名版本 #

text
┌─────────────────────────────────────────────────────────────┐
│                    子域名版本                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  格式:v{version}.api.example.com/resource                  │
│                                                             │
│  示例:                                                      │
│  GET https://v1.api.example.com/users                       │
│  GET https://v2.api.example.com/users                       │
│                                                             │
│  优点:                                                      │
│  ✅ URL 路径不变                                            │
│  ✅ 可以独立部署                                            │
│  ✅ 易于负载均衡                                            │
│                                                             │
│  缺点:                                                      │
│  ❌ DNS 配置复杂                                            │
│  ❌ SSL 证书管理复杂                                        │
│  ❌ 跨域问题                                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

策略对比 #

text
┌─────────────────────────────────────────────────────────────┐
│                    版本策略对比                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  策略          直观性  缓存性  RESTful  浏览器  推荐度      │
│  ─────────────────────────────────────────────────────────  │
│  URL 路径      ⭐⭐⭐   ⭐⭐⭐   ⭐⭐     ⭐⭐⭐   ⭐⭐⭐       │
│  Header        ⭐      ⭐⭐     ⭐⭐⭐   ⭐      ⭐⭐         │
│  查询参数      ⭐⭐⭐   ⭐      ⭐⭐     ⭐⭐⭐   ⭐⭐         │
│  子域名        ⭐⭐     ⭐⭐⭐   ⭐⭐⭐   ⭐⭐     ⭐          │
│                                                             │
│  推荐:                                                      │
│  - 公开 API:URL 路径版本                                   │
│  - 内部 API:Header 版本                                    │
│  - 简单场景:查询参数版本                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

版本生命周期管理 #

版本生命周期 #

text
┌─────────────────────────────────────────────────────────────┐
│                    版本生命周期                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐     │
│  │  开发   │──►│  发布   │──►│  维护   │──►│  废弃   │     │
│  └─────────┘   └─────────┘   └─────────┘   └─────────┘     │
│                                                             │
│  开发阶段:                                                  │
│  - 开发新版本功能                                           │
│  - 内部测试                                                 │
│  - 文档编写                                                 │
│                                                             │
│  发布阶段:                                                  │
│  - 灰度发布                                                 │
│  - 监控反馈                                                 │
│  - 全量发布                                                 │
│                                                             │
│  维护阶段:                                                  │
│  - Bug 修复                                                 │
│  - 安全更新                                                 │
│  - 小功能优化                                               │
│                                                             │
│  废弃阶段:                                                  │
│  - 发布废弃公告                                             │
│  - 提供迁移指南                                             │
│  - 设置过期时间                                             │
│  - 最终下线                                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

废弃 API 处理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    废弃 API 处理                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 添加废弃警告 Header                                      │
│  ─────────────────────────────────────────────              │
│  HTTP/1.1 200 OK                                            │
│  Deprecation: true                                          │
│  Sunset: Sat, 31 Dec 2025 23:59:59 GMT                     │
│  Link: </v2/users>; rel="successor-version"                │
│                                                             │
│  2. 响应体中添加警告信息                                     │
│  ─────────────────────────────────────────────              │
│  {                                                          │
│    "data": [...],                                           │
│    "warning": {                                             │
│      "code": "DEPRECATED_API",                              │
│      "message": "This API version is deprecated",           │
│      "sunset": "2025-12-31",                                │
│      "migrationGuide": "https://docs.example.com/migration" │
│    }                                                        │
│  }                                                          │
│                                                             │
│  3. 提供迁移时间表                                           │
│  ─────────────────────────────────────────────              │
│  - 发布日期:2025-01-01                                     │
│  - 废弃公告:2025-06-01                                     │
│  - 过期日期:2025-12-31                                     │
│  - 下线日期:2026-01-01                                     │
│                                                             │
│  4. 过期后返回 410 Gone                                      │
│  ─────────────────────────────────────────────              │
│  HTTP/1.1 410 Gone                                          │
│                                                             │
│  {                                                          │
│    "error": {                                               │
│      "code": "API_VERSION_RETIRED",                         │
│      "message": "API v1 has been retired",                  │
│      "migrationGuide": "https://docs.example.com/migration" │
│    }                                                        │
│  }                                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

版本管理最佳实践 #

text
┌─────────────────────────────────────────────────────────────┐
│                    版本管理最佳实践                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 向后兼容优先                                             │
│     - 尽量避免 Breaking Changes                             │
│     - 新增功能使用可选字段                                  │
│     - 保留旧字段一段时间                                    │
│                                                             │
│  2. 提前通知                                                 │
│     - 提前 6 个月发布废弃公告                               │
│     - 提供详细的迁移指南                                    │
│     - 提供示例代码                                          │
│                                                             │
│  3. 渐进式迁移                                               │
│     - 支持多版本共存                                        │
│     - 提供迁移工具                                          │
│     - 监控旧版本使用情况                                    │
│                                                             │
│  4. 文档更新                                                 │
│     - 每个版本独立文档                                      │
│     - 明确标注版本差异                                      │
│     - 提供变更日志                                          │
│                                                             │
│  5. 版本策略一致                                             │
│     - 整个 API 使用统一的版本策略                           │
│     - 不要混用多种版本策略                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

版本管理检查清单 #

text
□ 版本策略
  □ 选择合适的版本策略
  □ 团队统一使用
  □ 文档说明清楚

□ 版本发布
  □ 遵循语义化版本规范
  □ 提供变更日志
  □ 更新 API 文档

□ 版本废弃
  □ 提前发布废弃公告
  □ 提供迁移指南
  □ 设置合理的过渡期
  □ 监控旧版本使用情况

□ 版本下线
  □ 确认所有客户端已迁移
  □ 返回 410 Gone
  □ 保留文档供参考

下一步 #

现在你已经了解了 API 版本管理,接下来学习 API 安全,深入了解如何保护 API 安全!

最后更新:2026-03-29