Building REST APIs with Express
Express setup, routing and route params, middleware chain, JSON body parsing and validation, error handling, and project structure for maintainable APIs.
Minimal API
import express from 'express';
const app = express();
// 内置中间件
app.use(express.json()); // 解析 JSON body
app.use(express.urlencoded({ extended: true }));
app.get('/health', (req, res) => res.json({ ok: true }));
app.listen(3000, () => console.log('api on :3000'));
Routing, Params and Validation
import { Router } from 'express';
import { body, validationResult } from 'express-validator';
const users = Router();
users.get('/:id', (req, res) => {
res.json({ id: req.params.id, filter: req.query.q });
});
users.post('/',
body('name').isLength({ min: 2 }),
body('email').isEmail(),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() });
res.status(201).json(req.body);
});
app.use('/api/users', users); // 挂载路由器
Middleware Chain
An Express app is a stack of middleware: each function receives (req, res, next) and either ends the response or calls next(). This is where logging, auth, CORS and rate limiting live.
// 计时中间件
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
console.log(req.method, req.originalUrl, res.statusCode, Date.now() - start, 'ms');
});
next();
});
// 错误处理中间件(四个参数,放最后)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({ error: err.message || 'server error' });
});
// 常用生态
// morgan 日志 / helmet 安全头 / cors / express-rate-limit / cookie-session
Project Structure
src/
├── routes/ # 路由定义(Express Router)
├── controllers/ # 请求/响应处理
├── services/ # 业务逻辑(与框架无关)
├── models/ # 数据访问(Prisma / TypeORM)
├── middlewares/ # 自定义中间件
└── app.js # 组装
Keep controllers thin: move business logic into services and data access into models, so the HTTP layer can be swapped or tested without touching the core.
最小 API
import express from 'express';
const app = express();
// 内置中间件
app.use(express.json()); // 解析 JSON body
app.use(express.urlencoded({ extended: true }));
app.get('/health', (req, res) => res.json({ ok: true }));
app.listen(3000, () => console.log('api on :3000'));
路由、参数与校验
import { Router } from 'express';
import { body, validationResult } from 'express-validator';
const users = Router();
users.get('/:id', (req, res) => {
res.json({ id: req.params.id, filter: req.query.q });
});
users.post('/',
body('name').isLength({ min: 2 }),
body('email').isEmail(),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() });
res.status(201).json(req.body);
});
app.use('/api/users', users); // 挂载路由器
中间件链
Express 应用就是中间件栈:每个函数收到 (req, res, next),要么结束响应,要么调用 next()。日志、鉴权、CORS、限流都写在这里。
// 计时中间件
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
console.log(req.method, req.originalUrl, res.statusCode, Date.now() - start, 'ms');
});
next();
});
// 错误处理中间件(四个参数,放最后)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({ error: err.message || 'server error' });
});
// 常用生态
// morgan 日志 / helmet 安全头 / cors / express-rate-limit / cookie-session
项目结构
src/
├── routes/ # 路由定义(Express Router)
├── controllers/ # 请求/响应处理
├── services/ # 业务逻辑(与框架无关)
├── models/ # 数据访问(Prisma / TypeORM)
├── middlewares/ # 自定义中间件
└── app.js # 组装
保持 controller 轻薄:业务逻辑下沉到 service,数据访问收敛到 model,HTTP 层可以随时替换或单独测试。