skill/skills/backend/api-development/SKILL.md
后端API开发方法论,包括RESTful/GraphQL设计、请求验证、错误处理和安全实现
npx skillsauth add echovic/boss-skill backend/api-developmentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
实现 API 前,必须阅读 architecture.md §5(API 设计),获取:
| 操作 | HTTP 方法 | 路径 | 说明 |
|------|-----------|------|------|
| 列表 | GET | /api/users | 获取用户列表 |
| 详情 | GET | /api/users/:id | 获取单个用户 |
| 创建 | POST | /api/users | 创建新用户 |
| 更新 | PUT/PATCH | /api/users/:id | 更新用户 |
| 删除 | DELETE | /api/users/:id | 删除用户 |
成功响应:
{
"success": true,
"data": { ... },
"message": "Operation successful"
}
错误响应:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
}
}
请求参数:
GET /api/users?page=1&pageSize=20&sortBy=createdAt&order=desc
响应格式:
{
"success": true,
"data": {
"items": [...],
"pagination": {
"page": 1,
"pageSize": 20,
"total": 100,
"totalPages": 5
}
}
}
// 使用验证库(如 Zod、Joi、class-validator)
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(0).max(150).optional(),
});
// 在路由处理器中验证
app.post('/api/users', async (req, res) => {
try {
const validatedData = CreateUserSchema.parse(req.body);
const user = await userService.create(validatedData);
res.json({ success: true, data: user });
} catch (error) {
if (error instanceof z.ZodError) {
res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid input data',
details: error.errors,
},
});
}
}
});
| 错误类型 | HTTP 状态码 | 错误码 | 说明 | |----------|-------------|--------|------| | 验证错误 | 400 | VALIDATION_ERROR | 输入数据不合法 | | 认证错误 | 401 | UNAUTHORIZED | 未登录或 Token 无效 | | 权限错误 | 403 | FORBIDDEN | 无权限访问资源 | | 资源不存在 | 404 | NOT_FOUND | 请求的资源不存在 | | 冲突错误 | 409 | CONFLICT | 资源冲突(如重复创建) | | 服务器错误 | 500 | INTERNAL_ERROR | 服务器内部错误 |
// errorHandler.ts
export function errorHandler(err: Error, req: Request, res: Response, next: NextFunction) {
console.error(err);
if (err instanceof ValidationError) {
return res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: err.message,
details: err.details,
},
});
}
if (err instanceof NotFoundError) {
return res.status(404).json({
success: false,
error: {
code: 'NOT_FOUND',
message: err.message,
},
});
}
// 默认 500 错误
res.status(500).json({
success: false,
error: {
code: 'INTERNAL_ERROR',
message: 'An unexpected error occurred',
},
});
}
JWT Token 示例:
import jwt from 'jsonwebtoken';
// 生成 Token
export function generateToken(userId: string): string {
return jwt.sign({ userId }, process.env.JWT_SECRET!, {
expiresIn: '7d',
});
}
// 验证 Token 中间件
export function authMiddleware(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: 'No token provided' },
});
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: 'Invalid token' },
});
}
}
基于角色的访问控制(RBAC):
export function requireRole(...roles: string[]) {
return (req: Request, res: Response, next: NextFunction) => {
if (!req.user || !roles.includes(req.user.role)) {
return res.status(403).json({
success: false,
error: { code: 'FORBIDDEN', message: 'Insufficient permissions' },
});
}
next();
};
}
// 使用
app.delete('/api/users/:id', authMiddleware, requireRole('admin'), deleteUser);
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 分钟
max: 100, // 最多 100 个请求
message: 'Too many requests, please try again later',
});
app.use('/api/', limiter);
职责:处理 HTTP 请求和响应
// controllers/userController.ts
export class UserController {
async getUser(req: Request, res: Response) {
try {
const user = await userService.getById(req.params.id);
res.json({ success: true, data: user });
} catch (error) {
next(error);
}
}
async createUser(req: Request, res: Response) {
const validatedData = CreateUserSchema.parse(req.body);
const user = await userService.create(validatedData);
res.status(201).json({ success: true, data: user });
}
}
职责:业务逻辑封装
// services/userService.ts
export class UserService {
async getById(id: string): Promise<User> {
const user = await userRepository.findById(id);
if (!user) {
throw new NotFoundError('User not found');
}
return user;
}
async create(data: CreateUserDto): Promise<User> {
// 检查邮箱唯一性
const existing = await userRepository.findByEmail(data.email);
if (existing) {
throw new ConflictError('Email already exists');
}
// 创建用户
return userRepository.create(data);
}
}
职责:数据库操作
// repositories/userRepository.ts
export class UserRepository {
async findById(id: string): Promise<User | null> {
return db.user.findUnique({ where: { id } });
}
async findByEmail(email: string): Promise<User | null> {
return db.user.findUnique({ where: { email } });
}
async create(data: CreateUserDto): Promise<User> {
return db.user.create({ data });
}
}
| 级别 | 使用场景 | |------|----------| | ERROR | 错误和异常 | | WARN | 警告信息 | | INFO | 关键操作(登录、创建、删除) | | DEBUG | 调试信息 |
import winston from 'winston';
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
// 使用
logger.info('User created', { userId: user.id, email: user.email });
logger.error('Database connection failed', { error: err.message });
import Redis from 'ioredis';
const redis = new Redis();
async function getUserWithCache(id: string): Promise<User> {
// 尝试从缓存获取
const cached = await redis.get(`user:${id}`);
if (cached) {
return JSON.parse(cached);
}
// 从数据库获取
const user = await userRepository.findById(id);
// 写入缓存(5 分钟过期)
await redis.setex(`user:${id}`, 300, JSON.stringify(user));
return user;
}
实现 API 前:
实现 API 后:
testing
交互规范,定义加载状态、空状态、反馈机制、动效、无障碍等交互细节
content-media
设计变体模式,产出2-3个设计方案及 tradeoff 分析,供用户选择后确定最终方案
content-media
设计系统规范,包含颜色、字体、间距、圆角、阴影、动效等基础设计token
testing
UI组件规范,定义按钮、输入框、卡片等基础组件的变体、尺寸、状态