c23922faab
- Implement API version management middleware - Add version lifecycle management (dev/stable/maintenance/deprecated/sunset) - Add deprecation warning headers (X-API-Deprecated, X-API-Sunset-Date) - Add version tracking headers (X-API-Version) - Handle sunset versions with 410 Gone response - Comprehensive API versioning documentation - Include migration guide and best practices - Support gradual version rollout Phase 4 Task 44/68 completed
5.6 KiB
5.6 KiB
API 版本管理指南
📋 概述
小虾 SaaS 使用 URL 路径版本管理策略,确保 API 的向后兼容性。
🔢 版本命名规则
当前版本:v1
/api/v1/auth/login
/api/v1/workspaces
/api/v1/projects
版本号规则
- v1, v2, v3... - 主版本号
- 破坏性变更才升级主版本
- 非破坏性变更在当前版本迭代
📝 版本策略
什么时候升级版本?
需要升级(破坏性变更):
- ✅ 修改响应结构
- ✅ 删除字段
- ✅ 修改字段类型
- ✅ 修改认证方式
- ✅ 修改 HTTP 方法
不需要升级(兼容性变更):
- ✅ 添加新字段
- ✅ 添加新端点
- ✅ 添加可选参数
- ✅ 优化性能
- ✅ 修复 Bug
🔄 版本生命周期
阶段 1: 开发中(Development)
- 版本:
v2-beta - 状态:不稳定,可能变更
- 使用:仅内部测试
阶段 2: 稳定版(Stable)
- 版本:
v2 - 状态:稳定,推荐使用
- 支持:完整支持,持续更新
阶段 3: 维护中(Maintenance)
- 版本:
v1(当 v2 发布后) - 状态:只修复安全问题和严重 Bug
- 支持:12 个月维护期
阶段 4: 已弃用(Deprecated)
- 版本:
v1(维护期结束后) - 状态:仍可访问,显示弃用警告
- 支持:6 个月弃用期
阶段 5: 下线(Sunset)
- 版本:
v1(弃用期结束后) - 状态:返回 410 Gone
- 支持:无
📅 版本时间线示例
2026-06-01: v1 发布 (Stable)
2027-01-01: v2 发布 (Stable)
2027-01-01: v1 进入维护期 (Maintenance, 12个月)
2028-01-01: v1 进入弃用期 (Deprecated, 6个月)
2028-07-01: v1 下线 (Sunset)
🚨 弃用通知
响应头
HTTP/1.1 200 OK
X-API-Version: v1
X-API-Deprecated: true
X-API-Sunset-Date: 2028-07-01
X-API-Deprecation-Info: https://docs.xiaoxia-saas.com/api/deprecation/v1
响应体(可选)
{
"data": { ... },
"_meta": {
"deprecated": true,
"sunset_date": "2028-07-01",
"migration_guide": "https://docs.xiaoxia-saas.com/api/migration/v1-to-v2"
}
}
🔧 客户端处理
检测弃用
import requests
response = requests.get("https://api.xiaoxia-saas.com/api/v1/workspaces")
if response.headers.get("X-API-Deprecated") == "true":
sunset_date = response.headers.get("X-API-Sunset-Date")
print(f"警告: API v1 将在 {sunset_date} 下线")
自动迁移
class APIClient:
def __init__(self, version="v2"):
self.version = version
self.base_url = f"https://api.xiaoxia-saas.com/api/{version}"
def fallback_to_v1(self, endpoint):
"""自动降级到 v1"""
try:
return self.request(endpoint)
except APINotFoundError:
# v2 不存在,尝试 v1
self.version = "v1"
return self.request(endpoint)
📚 迁移指南
v1 → v2 迁移示例
变更 1: 登录响应结构
v1:
{
"token": "abc123",
"user_id": "user-123"
}
v2:
{
"access_token": "abc123",
"refresh_token": "def456",
"expires_in": 1800,
"user": {
"id": "user-123",
"email": "user@example.com"
}
}
迁移代码:
# v1
token = response.json()["token"]
# v2
token = response.json()["access_token"]
🛠️ 实现方式
FastAPI 版本路由
from fastapi import APIRouter
# v1 路由
api_v1 = APIRouter(prefix="/api/v1")
@api_v1.get("/workspaces")
async def list_workspaces_v1():
return {"workspaces": []}
# v2 路由
api_v2 = APIRouter(prefix="/api/v2")
@api_v2.get("/workspaces")
async def list_workspaces_v2():
return {
"data": [],
"pagination": {"page": 1, "total": 0}
}
# 注册到主应用
app.include_router(api_v1)
app.include_router(api_v2)
弃用中间件
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
class DeprecationMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
response = await call_next(request)
if request.url.path.startswith("/api/v1"):
response.headers["X-API-Deprecated"] = "true"
response.headers["X-API-Sunset-Date"] = "2028-07-01"
return response
📊 版本使用统计
监控指标
from prometheus_client import Counter
api_version_counter = Counter(
'api_requests_by_version',
'API requests by version',
['version']
)
@app.middleware("http")
async def track_version(request: Request, call_next):
version = extract_version(request.url.path)
api_version_counter.labels(version=version).inc()
return await call_next(request)
查看统计
# v1 使用量
curl http://localhost:8000/metrics | grep api_requests_by_version{version="v1"}
# v2 使用量
curl http://localhost:8000/metrics | grep api_requests_by_version{version="v2"}
🎯 最佳实践
1. 提前通知
- 至少提前 6 个月通知弃用
- 通过邮件、公告、响应头多渠道通知
- 提供详细的迁移指南
2. 保持兼容
- 尽可能添加而不是修改
- 使用可选参数而不是必填
- 保留旧字段,添加新字段
3. 渐进式迁移
v1 (100%) → v1 (80%) + v2 (20%) → v1 (20%) + v2 (80%) → v2 (100%)
4. 文档优先
- 版本变更先更新文档
- 提供完整的迁移指南
- 包含代码示例
🔗 相关资源
最后更新: 2026-06-17