
关于
构建生产级 REST API 端点,包含验证、错误处理、认证和文档。遵循安全性和可扩展性最佳实践。
name: api-endpoint-builder description: "构建具有验证、错误处理、认证和文档的生产就绪 REST API 端点。遵循安全性和可扩展性的最佳实践。" category: development risk: safe source: community date_added: "2026-03-05"
API 端点构建器
构建完整的、生产就绪的 REST API 端点,包含适当的验证、错误处理、认证和文档。
何时使用此技能
- 用户要求"创建 API 端点"或"构建 REST API"
- 构建新的后端功能
- 向现有 API 添加端点
- 用户提到"API"、"端点"、"路由"或"REST"
- 创建 CRUD 操作
你将构建什么
对于每个端点,你需要创建:
- 使用正确 HTTP 方法的路由处理器
- 输入验证(请求体、参数、查询)
- 认证/授权检查
- 业务逻辑
- 错误处理
- 响应格式化
- API 文档
- 测试(如果请求)
端点结构
1. 路由定义
// Express example
router.post('/api/users', authenticate, validateUser, createUser);
// Fastify example
fastify.post('/api/users', {
preHandler: [authenticate],
schema: userSchema
}, createUser);
2. 输入验证
处理前始终验证:
const validateUser = (req, res, next) => {
const { email, name, password } = req.body;
if (!email || !email.includes('@')) {
return res.status(400).json({ error: 'Valid email required' });
}
if (!name || name.length < 2) {
return res.status(400).json({ error: 'Name must be at least 2 characters' });
}
if (!password || password.length < 8) {
return res.status(400).json({ error: 'Password must be at least 8 characters' });
}
next();
};
3. 处理器实现
const createUser = async (req, res) => {
try {
const { email, name, password } = req.body;
// Check if user exists
const existing = await db.users.findOne({ email });
if (existing) {
return res.status(409).json({ error: 'User already exists' });
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
// Create user
const user = await db.users.create({
email,
name,
password: hashedPassword,
createdAt: new Date()
});
// Don't return password
const { password: _, ...userWithoutPassword } = user;
res.status(201).json({
success: true,
data: userWithoutPassword
});
} catch (error) {
console.error('Create user error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
最佳实践
HTTP 状态码
200- 成功(GET、PUT、PATCH)201- 已创建(POST)204- 无内容(DELETE)400- 错误请求(验证失败)401- 未认证(未登录)403- 禁止(未授权)404- 未找到409- 冲突(重复)500- 内部服务器错误
响应格式
一致的结构:
// Success
{
"success": true,
"data": { ... }
}
// Error
{
"error": "Error message",
"details": { ... } // optional
}
// List with pagination
{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 100
}
}
安全检查清单
- [ ] 受保护路由需要认证
- [ ] 授权检查(用户拥有资源)
- [ ] 所有字段的输入验证
- [ ] SQL 注入防护(使用参数化查询)
- [ ] 公共端点的速率限制
- [ ] 响应中无敏感数据(密码、令牌)
- [ ] CORS 正确配置
- [ ] 设置请求大小限制
错误处理
// Centralized error handler
app.use((err, req, res, next) => {
console.error(err.stack);
// Don't leak error details in production
const message = process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message;
res.status(err.status || 500).json({ error: message });
});
常见模式
CRUD 操作
// Create
POST /api/resources
Body: { name, description }
// Read (list)
GET /api/resources?page=1&limit=20
// Read (single)
GET /api/resources/:id
// Update
PUT /api/resources/:id
Body: { name, description }
// Delete
DELETE /api/resources/:id
分页
const getResources = async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const skip = (page - 1) * limit;
const [resources, total] = await Promise.all([
db.resources.find().skip(skip).limit(limit),
db.resources.countDocuments()
]);
res.json({
success: true,
data: resources,
pagination: {
page,
limit,
total,
pages: Math.ceil(total / limit)
}
});
};
过滤与排序
const getResources = async (req, res) => {
const { status, sort, order } = req.query;
const filter = {};
if (status) filter.status = status;
const sortObj = {};
if (sort) sortObj[sort] = order === 'desc' ? -1 : 1;
const resources = await db.resources.find(filter).sort(sortObj);
res.json({ success: true, data: resources });
};
兼容工具
Claude CodeCursor
标签
后端开发
