# 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 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 ``` ### 响应体(可选) ```json { "data": { ... }, "_meta": { "deprecated": true, "sunset_date": "2028-07-01", "migration_guide": "https://docs.xiaoxia-saas.com/api/migration/v1-to-v2" } } ``` --- ## 🔧 客户端处理 ### 检测弃用 ```python 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} 下线") ``` ### 自动迁移 ```python 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: ```json { "token": "abc123", "user_id": "user-123" } ``` v2: ```json { "access_token": "abc123", "refresh_token": "def456", "expires_in": 1800, "user": { "id": "user-123", "email": "user@example.com" } } ``` **迁移代码:** ```python # v1 token = response.json()["token"] # v2 token = response.json()["access_token"] ``` --- ## 🛠️ 实现方式 ### FastAPI 版本路由 ```python 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) ``` ### 弃用中间件 ```python 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 ``` --- ## 📊 版本使用统计 ### 监控指标 ```python 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) ``` ### 查看统计 ```bash # 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. 文档优先 - 版本变更先更新文档 - 提供完整的迁移指南 - 包含代码示例 --- ## 🔗 相关资源 - [语义化版本规范](https://semver.org/) - [API 版本管理最佳实践](https://restfulapi.net/versioning/) - [Stripe API 版本管理](https://stripe.com/docs/api/versioning) --- **最后更新:** 2026-06-17