Node.js 开发手册NODE.JS

CHAPTER 05应用层 · WEB

Web 后端框架

HTTP 基础、Express/Fastify、中间件、路由与请求生命周期。落地一个真实可运行的 API 服务。

开始阅读难度中级先修前三章约3小时
05.1

HTTP 基础回顾

REST API 围绕方法(GET/POST/PUT/DELETE)、状态码(2xx 成功、4xx 客户端、5xx 服务端)、头部与 JSON 体。Node 框架帮你解析这些原语。

状态码含义场景
200OKGET 成功
201CreatedPOST 创建成功
400/401/403客户端错误参数错/未登录/无权限
404Not Found资源不存在
500Server Error未捕获异常
05.2

Express 入门

Express 是最小、最成熟的 Node Web 框架:一个 app 实例,用方法注册路由,监听端口。

import express from 'express';
const app = express();
app.use(express.json());          // 解析 JSON 请求体

app.get('/health', (req, res) => {
  res.json({ ok: true });
});

app.listen(3000, () => console.log('listening :3000'));
05.3

路由与参数

路由由方法 + 路径组成,路径可含 :param 动态段;查询参数在 req.query,体在 req.body。

app.get('/users/:id', (req, res) => {
  const { id } = req.params;           // 路径参数
  const { fields } = req.query;        // 查询参数
  res.json({ id, fields });
});

app.post('/users', (req, res) => {
  const user = req.body;               // 已解析的 JSON
  res.status(201).json(user);
});
05.4

中间件模型

中间件是"处理请求的函数链":(req, res, next) => {}。依次执行,调用 next() 传给下一个;可做日志、鉴权、校验。

function logger(req, res, next) {
  console.log(req.method, req.url);
  next();                              // 必须调用,否则请求挂起
}
app.use(logger);                       // 全局中间件
app.use('/admin', authGuard);          // 路径限定中间件
忘记 next / 不响应

中间件既不 next() 也不 res.send,请求会一直挂起直到超时。每个分支都要"放行或响应"。

05.5

错误处理

Express 用"4 参数中间件"集中处理错误:(err, req, res, next)。业务里 next(err) 即可跳转到它。

app.get('/x', (req, res, next) => {
  try { throw new Error('boom'); }
  catch (e) { next(e); }
});

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).json({ error: err.message });
});
05.6

Fastify 简介

Fastify 以性能著称,内置 JSON schema 校验与序列化,吞吐高于 Express。API 风格相似但更结构化。

import Fastify from 'fastify';
const app = Fastify();

app.get('/users/:id', {
  schema: { params: { id: { type: 'string' } } }
}, async (req) => ({ id: req.params.id }));

await app.listen({ port: 3000 });
选型

需要极致吞吐与内置校验选 Fastify;生态成熟度与中间件丰富度选 Express;轻量与洋葱模型选 Koa。

05.7

Koa 与对比

Koa 由 Express 原班人马打造,基于 async 中间件(洋葱模型),本身极简,功能靠中间件拼装。

import Koa from 'koa';
const app = new Koa();
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();                        // 进入下游
  ctx.set('X-Response-Time', Date.now() - start);
});
app.use(async ctx => { ctx.body = 'hi'; });
app.listen(3000);
05.8

常见陷阱与 FAQ

body 是 undefined 怎么办?

忘记 express.json() 中间件。GET 请求本就没有 body。确保在路由前挂载解析中间件。

异步路由里 throw 会怎样?

Express 5 之前不会自动捕获 async 抛错,需 try/catch + next(err) 或用包装函数。Fastify 会自动处理 async 抛错。

全局中间件顺序重要吗?

非常重要。错误处理中间件必须放最后;鉴权中间件要放在受保护路由之前。顺序即执行顺序。

05.9

实战练习与资源

延伸资源