RESTful API 进阶实践与性能优化
接口版本控制
API 需要持续迭代,版本控制是保证向后兼容的关键。
版本控制策略
- URL 路径:/api/v1/users、/api/v2/users(推荐)
- 请求头:Accept: application/vnd.api+json;version=1
- 查询参数:/api/users?version=1
Koa.js 版本控制示例
// middleware/version.js
const versionMap = {
'v1': require('../controllers/v1/users'),
'v2': require('../controllers/v2/users')
};
module.exports = async (ctx, next) => {
const version = ctx.params.version || 'v1';
ctx.apiVersion = version;
ctx.apiController = versionMap[version] || versionMap.v1;
await next();
};
数据缓存策略
HTTP 缓存
- Cache-Control:缓存时间、public/private、no-cache
- ETag:资源版本标识
- Last-Modified:最后修改时间
服务端缓存
- Redis 缓存热点数据
- 本地内存缓存(进程内)
- 多级缓存:本地 + Redis
缓存实现示例
// 缓存中间件
const cache = new Map();
async function cacheMiddleware(ctx, next) {
const key = ctx.url;
// GET 请求尝试读取缓存
if (ctx.method === 'GET' && cache.has(key)) {
const { data, expire } = cache.get(key);
if (Date.now() < expire) {
ctx.set('X-Cache', 'HIT');
ctx.body = data;
return;
}
cache.delete(key);
}
await next();
// 写入缓存
if (ctx.status === 200 && ctx.method === 'GET') {
cache.set(key, {
data: ctx.body,
expire: Date.now() + 60 * 1000 // 1分钟
});
ctx.set('X-Cache', 'MISS');
}
}
分页优化
-offset 分页
传统分页方式,大偏移量时性能差:
?page=1&limit=20 // SQL: LIMIT 20 OFFSET 0
游标分页(推荐)
基于上一页最后一条记录的 ID,性能稳定:
?cursor=abc123&limit=20 // SQL: WHERE id > 'abc123' LIMIT 20
限流与熔断
限流策略
- 固定窗口:每分钟 100 次请求
- 滑动窗口:更平滑的限流
- 漏桶算法:匀速处理请求
- 令牌桶:允许突发流量
熔断降级
- 连续失败 N 次后触发熔断
- 熔断期间直接返回默认值
- 超时自动恢复
- 降级策略:返回缓存数据、简化响应
Rate Limit 中间件
const ratelimit = require('koa-ratelimit');
const Redis = require('ioredis');
app.use(ratelimit({
driver: 'redis',
db: new Redis(),
duration: 60000,
errorMessage: '请求过于频繁,请稍后重试',
key: ctx => ctx.ip,
max: 100,
disableHeader: false
}));
接口安全
- HTTPS:全站 HTTPS
- 参数校验:使用 Joi/Validator.js
- SQL 注入:参数化查询
- XSS:输入过滤、输出转义
- CORS:合理配置跨域策略
- 请求超时:设置合理超时时间
API 文档
推荐使用 Swagger/OpenAPI 规范:
- Swagger UI:可視化文档
- Redoc:更美观的文档
- 自动生成客户端 SDK