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
304 lines
5.6 KiB
Markdown
304 lines
5.6 KiB
Markdown
# 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
|