Express.js REST API Patterns
概览
Express.js 是一个最小且灵活的 Node.js Web 应用程序框架,用于构建 REST APIs,特点是强大的中间件系统、灵活的路由和庞大的生态系统。
Express.js 包含:
- 最小核心:最小核心,拥有强大的中间件系统
- 灵活路由:带有路由参数的灵活路由
- 中间件堆栈:用于请求/响应处理的中间件堆栈
- 错误处理:内置错误处理
- 安全:安全中间件和最佳实践
- 生产就绪:通过集群和优雅关闭实现生产就绪
为什么这很重要
- 提高开发速度:Express.js 可以提高开发速度 30-50%
- 减少上市时间:灵活的框架有助于减少上市时间
- 提高可扩展性:集群和中间件提高可扩展性
- 降低维护成本:结构良好的代码降低维护成本
- 增强性能:优化的中间件增强性能
核心概念
1. 应用设置
import express, { Application } from "express"
export function createApp(): Application {
const app = express()
// 中间件
app.use(express.json())
// 路由
app.use("/api", routes)
return app
}
2. 中间件模式
中间件顺序至关重要:
- 安全头 (Helmet)
- CORS
- 请求日志 (Morgan)
- 正文解析
- 请求 ID
- 速率限制
- 认证
- 路由
- 错误处理(必须是最后)
export function createApp(): Application {
const app = express()
// 1. 安全头 (首先)
app.use(helmet())
// 2. CORS
app.use(cors())
// 3. 请求日志
app.use(morgan("combined"))
// 4. 正文解析
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// 5. 自定义中间件
app.use(requestIdMiddleware)
app.use(loggingMiddleware)
// 6. 认证(在路由之前)
app.use(authMiddleware)
// 7. 路由
app.use("/api", routes)
// 8. 错误处理(最后)
app.use(errorHandler)
return app
}
3. 路由
import { Router } from "express"
const router = Router()
// CRUD 路由
router.get("/users", userController.getAll)
router.get("/users/:id", userController.getById)
router.post("/users", userController.create)
router.put("/users/:id", userController.update)
router.delete("/users/:id", userController.delete)
export default router
4. 错误处理
export function errorHandler(
error: Error,
req: Request,
res: Response,
next: NextFunction
): void {
logger.error(error, { path: req.path, method: req.method })
if (error instanceof AppError) {
return res.status(error.statusCode).json({
success: false,
message: error.message,
...(error.details && { details: error.details }),
})
}
res.status(500).json({
success: false,
message: process.env.NODE_ENV === "production"
? "Internal server error"
: error.message,
})
}
5. 请求验证
Express Validator:
import { body, validationResult } from "express-validator"
export const validateUser = [
body("name")
.trim()
.notEmpty()
.withMessage("姓名是必需的")
.isLength({ min: 2, max: 50 }),
body("email")
.trim()
.isEmail()
.withMessage("无效的电子邮件地址"),
]
export function handleValidationErrors(
req: Request,
res: Response,
next: NextFunction
): void {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: "验证失败",
errors: errors.array(),
})
}
next()
}
6. 认证
import jwt from "jsonwebtoken"
export function authMiddleware(req: Request, res: Response, next: NextFunction): void {
const authHeader = req.headers.authorization
if (!authHeader || !authHeader.startsWith("Bearer ")) {
throw new UnauthorizedError("未提供令牌")
}
const token = authHeader.substring(7)
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!)
req.user = decoded
next()
} catch (error) {
throw new UnauthorizedError("无效的令牌")
}
}
7. 速率限制
import rateLimit from "express-rate-limit"
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 分钟
max: 100, // 每个 IP 限制 100 个请求
message: "此 IP 请求过多",
})
app.use("/api", limiter)
快速开始
- 初始化 Express 应用:
npm init -y npm install express typescript @types/express - 创建基础服务器:
import express from "express" const app = express() app.listen(3000, () => console.log("服务器运行中")) - 添加中间件:
npm install helmet cors morgan - 创建路由:
const router = express.Router() router.get("/users", (req, res) => res.json({ users: [] })) - 启动服务器:
npm run dev
生产检查清单
- [ ] 使用 TypeScript 确保类型安全
- [ ] 实施适当的中间件顺序
- [ ] 使用 Helmet 添加安全头
- [ ] 适当配置 CORS
- [ ] 实施认证和授权
- [ ] 添加速率限制以防止滥用
- [ ] 使用 express-validator 或 Zod 进行输入验证
- [ ] 实施适当的错误处理
- [ ] 使用 Winston 添加日志
- [ ] 使用 async/await 进行异步操作
- [ ] 使用 Supertest 测试路由
- [ ] 添加健康检查端点
- [ ] 实施优雅关闭
- [ ] 在生产中使用集群
- [ ] 监控性能和错误
反模式
- 错误的中间件顺序:不要错误地排序中间件
- 缺少错误处理:不要未能适当处理错误
- 无输入验证:不要跳过输入验证
- 安全性差:不要未能实施安全措施
- 无日志记录:不要未能记录请求和错误
- 性能差:不要未能优化性能
集成点
- 错误处理:
03-backend-api/error-handling - 验证:
03-backend-api/validation - 中间件:
03-backend-api/middleware - API 设计:
01-foundations/api-design - 监控:
14-monitoring-observability