
API 版本管理策略
API 版本管理让你能够在不破坏现有客户端的情况下演进你的 API。
URL 路径版本管理
GET /api/v1/users
GET /api/v2/users
// Express.js
const v1Router = express.Router();
const v2Router = express.Router();
v1Router.get('/users', v1UserController.list);
v2Router.get('/users', v2UserController.list); // 增强的响应
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// NestJS
@Controller({ version: '1', path: 'users' })
class UsersV1Controller { }
@Controller({ version: '2', path: 'users' })
class UsersV2Controller { }
优点:简单、在 URL 中可见、易于路由 缺点:URL 应表示资源而非版本;缓存碎片化
标头版本管理
GET /api/users
Accept-Version: 1.0
# 或
API-Version: 2
// Express 中间件
function versionMiddleware(req: Request, res: Response, next: NextFunction) {
const version = req.header('API-Version') || req.header('Accept-Version') || '1';
req.apiVersion = parseInt(version);
next();
}
app.get('/api/users', versionMiddleware, (req, res) => {
if (req.apiVersion >= 2) {
return userController.listV2(req, res);
}
return userController.listV1(req, res);
});
优点:URL 整洁、符合 RESTful 风格 缺点:不够直观、在浏览器中测试较困难
内容协商(Accept 标头)
GET /api/users
Accept: application/vnd.myapp.v2+json
app.get('/api/users', (req, res) => {
const accept = req.header('Accept') || '';
if (accept.includes('vnd.myapp.v2')) {
return res.json(formatV2(users));
}
return res.json(formatV1(users));
});
弃用策略
// 添加弃用标头
app.use('/api/v1/*', (req, res, next) => {
res.set('Deprecation', 'true');
res.set('Sunset', 'Sat, 1 Jan 2026 00:00:00 GMT');
res.set('Link', '</api/v2>; rel="successor-version"');
next();
});
版本管理检查清单
- [ ] 定义什么是破坏性变更:
- 移除字段
- 更改字段类型
- 移除端点
- 更改认证方式
- [ ] 非破坏性变更不需要新版本:
- 添加可选字段
- 添加新端点
- 添加可选查询参数
- [ ] 向 API 消费者传达弃用日期
- [ ] 在宣布弃用后至少维护版本 12 个月
对于大多数 API,URL 版本管理在简单性和可见性之间提供了最佳平衡。