name: pitfalls-express-api description: “Express API 约定与存储模式。适用于构建 REST API、定义路由或实现存储接口。触发条件:Express、路由器、API 路由、状态码、存储接口。”
Express API 常见陷阱
Express API 的常见陷阱与正确模式。
何时使用
- 构建 REST API 路由
- 实现存储接口
- 设置 HTTP 状态码
- 验证请求体
- 审查 Express API 代码
工作流程
步骤 1:验证路由结构
检查路由是否遵循 REST 约定。
步骤 2:检查状态码
确保每个操作都返回正确的状态码。
步骤 3:验证输入验证
确认已配置输入验证中间件。
路由结构
// 公共路由
GET /api/resource // 列表
GET /api/resource/:id // 获取单个
// 管理员路由(带认证中间件)
POST /api/admin/resource // 创建 (201)
PATCH /api/admin/resource/:id // 更新 (200)
DELETE /api/admin/resource/:id // 删除 (204)
// ✅ 始终在存储前验证
router.post('/', validateBody(schema), async (req, res) => {
const validated = req.body; // 已由中间件验证
});
状态码
| 操作 | 成功 | 未找到 | 无效请求 |
|---|---|---|---|
| GET | 200 | 404 | 400 |
| POST | 201 | - | 400 |
| PATCH | 200 | 404 | 400 |
| DELETE | 204 | 404 | - |
存储接口模式
// ✅ 为所有存储操作定义接口
interface IStorage {
// 策略相关
getStrategies(): Promise<Strategy[]>;
getStrategy(id: string): Promise<Strategy | undefined>;
createStrategy(data: NewStrategy): Promise<Strategy>;
updateStrategy(id: string, data: Partial<Strategy>): Promise<Strategy | undefined>;
deleteStrategy(id: string): Promise<boolean>;
}
// ✅ 为不同后端实现
class DbStorage implements IStorage { ... } // PostgreSQL
class MemStorage implements IStorage { ... } // 测试用
后台作业模式
// ✅ 在进程退出时清理
const intervals: NodeJS.Timeout[] = [];
function startJob(fn: () => void, ms: number) {
const id = setInterval(fn, ms);
intervals.push(id);
return id;
}
process.on('SIGTERM', () => {
intervals.forEach(clearInterval);
process.exit(0);
});
// ✅ 处理重叠执行
let isRunning = false;
async function scanForOpportunities() {
if (isRunning) return;
isRunning = true;
try {
await scan();
} finally {
isRunning = false;
}
}
快速检查清单
- [ ] 路由遵循 REST 约定
- [ ] 返回正确的状态码
- [ ] 所有端点都有输入验证
- [ ] 使用了存储接口抽象
- [ ] 后台作业处理了清理工作