后端工程Technical Deep Dive
Express vs Fastify:企业级 Web 框架对比
发布时间2026/03/29
分类后端工程
预计阅读10 分钟
作者吴长龙
*
Express vs Fastify:企业级 Web 框架对比
01.内容
# Express vs Fastify:企业级 Web 框架对比
选择合适的 Web 框架是后端开发的第一步。Express 和 Fastify 是 Node.js 生态中最流行的两个框架,本文从性能、生态、易用性等多个维度进行深入对比,帮助你做出明智的选择。
02.一、背景与定位
Express:老牌霸主
Express 自 2009 年发布以来,一直是 Node.js Web 框架的事实标准。它的设计理念是"最小化 + 可扩展",通过中间件机制让开发者自由组织代码。
特点:
- •简单灵活的路由
- •丰富的中间件生态
- •几乎所有 Node.js 教程都使用 Express
Fastify:性能优先
Fastify 于 2016 年发布,定位是"高性能、低开销"的 Web 框架。它在设计时充分考虑了 TypeScript 支持和 Type safety。
特点:
- •基于 schema 的验证(JSON Schema)
- •极致的性能优化
- •内置日志系统
- •插件生态系统
03.二、性能对比
基准测试数据
根据多个独立测试机构的基准测试:
| 指标 | Express | Fastify | 差异 |
|---|---|---|---|
| QPS (Hello World) | ~15,000 | ~70,000 | Fastify 快 4-5x |
| 内存占用 | 较高 | 较低 | Fastify 省 30-50% |
| 首字节时间 (TTFB) | 较高 | 较低 | Fastify 更低 |
| 冷启动时间 | 较快 | 较快 | 相差不大 |
实际业务场景测试
javascript snippetjavascript
// 测试代码:模拟真实业务场景
const express = require('express');
const fastify = require('fastify');
// Express
const expressApp = express();
expressApp.get('/api/users/:id', (req, res) => {
const { id } = req.params;
// 模拟数据库查询
const user = { id, name: 'User ' + id, role: 'admin' };
res.json(user);
});
// Fastify
const fastifyApp = fastify({ logger: false });
fastifyApp.get('/api/users/:id', async (req, reply) => {
const { id } = req.params;
const user = { id, name: 'User ' + id, role: 'admin' };
return user;
});
// 两者在处理真实业务逻辑时性能差距会缩小
// 但 Fastify 仍然有 2-3x 的优势性能差异的根源
- •路由处理:Fastify 使用自定义的路由树,比 Express 的正则匹配更快
- •中间件机制:Express 的 use() 会遍历所有中间件,Fastify 采用更高效的 Hook 机制
- •Schema 验证:Fastify 在启动时编译 schema,运行时几乎零开销
- •对象复用:Fastify 复用请求/响应对象,减少 GC 压力
04.三、代码对比
3.1 基础路由
javascript snippetjavascript
// Express
const express = require('express');
const app = express();
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.post('/api/users', (req, res) => {
const user = req.body;
// 处理创建
res.status(201).json(user);
});
// Fastify
const fastify = require('fastify');
const app = fastify({ logger: true });
app.get('/api/users', async (request, reply) => {
return { users: [] };
});
app.post('/api/users', async (request, reply) => {
const user = request.body;
return reply.status(201).send(user);
});3.2 中间件 vs Hooks
javascript snippetjavascript
// Express 中间件
app.use((req, res, next) => {
console.log('请求开始:', req.method, req.url);
next();
});
app.use((req, res, next) => {
// 认证逻辑
if (req.headers.authorization) {
next();
} else {
res.status(401).json({ error: '未授权' });
}
});
// Fastify Hooks
app.addHook('onRequest', async (request, reply) => {
console.log('请求开始:', request.method, request.url);
});
app.addHook('preHandler', async (request, reply) => {
if (!request.headers.authorization) {
reply.status(401).send({ error: '未授权' });
}
});3.3 参数验证
javascript snippetjavascript
// Express:手动验证(繁琐)
app.post('/api/users', (req, res, next) => {
const { name, email } = req.body;
if (!name || name.length < 2) {
return res.status(400).json({ error: '名字至少2个字符' });
}
if (!email || !email.includes('@')) {
return res.status(400).json({ error: '无效的邮箱' });
}
next();
});
// Fastify:Schema 声明(声明式)
const createUserSchema = {
body: {
type: 'object',
required: ['name', 'email'],
properties: {
name: { type: 'string', minLength: 2 },
email: { type: 'string', format: 'email' }
}
},
response: {
201: {
type: 'object',
properties: {
id: { type: 'string' },
name: { type: 'string' },
email: { type: 'string' }
}
}
}
};
app.post('/api/users', { schema: createUserSchema }, async (request, reply) => {
const { name, email } = request.body;
// 创建用户
return reply.status(201).send({ id: '1', name, email });
});05.四、生态系统
4.1 中间件/插件
javascript snippetjavascript
// Express 生态
const helmet = require('helmet'); // 安全头
const cors = require('cors'); // 跨域
const morgan = require('morgan'); // 日志
const expressRateLimit = require('express-rate-limit'); // 限流
const bodyParser = require('body-parser'); // 解析
app.use(helmet());
app.use(cors());
app.use(morgan('dev'));
app.use(expressRateLimit({ windowMs: 15*60*1000, max: 100 }));
app.use(bodyParser.json());
// Fastify 生态(命名约定 @fastify/xxx)
await app.register(require('@fastify/helmet'));
await app.register(require('@fastify/cors'));
await app.register(require('@fastify/rate-limit'));
// Fastify 内置 body 解析,无需额外中间件4.2 TypeScript 支持
typescript snippettypescript
// Fastify 原生 TypeScript 支持
import Fastify, { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
interface UserParams {
id: string;
}
interface CreateUserBody {
name: string;
email: string;
}
const app: FastifyInstance = Fastify();
app.get<{ Params: UserParams }>('/api/users/:id', async (
request: FastifyRequest<{ Params: UserParams }>,
reply: FastifyReply
) => {
const { id } = request.params;
return { id, name: 'John' };
});
app.post<{ Body: CreateUserBody }>('/api/users', async (
request: FastifyRequest<{ Body: CreateUserBody }>,
reply: FastifyReply
) => {
const { name, email } = request.body;
return reply.status(201).send({ id: '1', name, email });
});
// Express 需要额外安装 @types/express
// 并且类型推断不如 Fastify 精确4.3 路由注册方式
javascript snippetjavascript
// Express 路由文件
// users.js
module.exports = (app) => {
app.get('/users', listUsers);
app.get('/users/:id', getUser);
app.post('/users', createUser);
};
// 路由拆分
const usersRouter = require('./routes/users');
const ordersRouter = require('./routes/orders');
app.use('/api/users', usersRouter);
app.use('/api/orders', ordersRouter);
// Fastify 路由拆分(推荐)
// users.js
async function userRoutes(fastify, options) {
fastify.get('/', listUsers);
fastify.get('/:id', getUser);
fastify.post('/', createUser);
}
// 插件化注册
await app.register(userRoutes, { prefix: '/api/users' });
await app.register(orderRoutes, { prefix: '/api/orders' });06.五、生产环境选择
5.1 何时选择 Express
| 场景 | 原因 |
|---|---|
| 快速原型开发 | 文档丰富,学习曲线低 |
| 维护现有项目 | 团队熟悉,生态成熟 |
| 简单 REST API | 功能足够,不需要极致性能 |
| 需要大量第三方中间件 | Express 中间件生态更丰富 |
5.2 何时选择 Fastify
| 场景 | 原因 |
|---|---|
| 高性能 API | 性能优势明显 |
| TypeScript 项目 | 原生 TS 支持 |
| 需要严格的输入验证 | 内置 JSON Schema |
| 微服务架构 | 轻量、快速启动 |
| 需要内置日志/监控 | 丰富的平台特性 |
5.3 企业级建议
javascript snippetjavascript
// 实际建议:根据团队和技术栈选择
// 小团队、快速迭代 -> Express
// 优势:学习成本低,招聘容易,文档丰富
// 大团队、性能敏感 -> Fastify
// 优势:类型安全,性能优异,内置功能多
// 或者:混合使用
// - 内部工具/管理后台:Express(开发快)
// - 对外 API 服务:Fastify(性能好)
// - 新项目:直接 Fastify(面向未来)07.六、迁移指南
从 Express 迁移到 Fastify
javascript snippetjavascript
// Step 1: 安装
// npm i fastify
// Step 2: 基本结构迁移
const express = require('express');
const app = express();
// 旧代码
app.use(express.json());
app.get('/api/health', (req, res) => res.json({ status: 'ok' }));
// 新代码
const fastify = require('fastify');
const app = fastify({ logger: true });
// Fastify 自动解析 JSON,无需中间件
app.get('/api/health', async () => ({ status: 'ok' }));
// Step 3: 错误处理
// Express
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: '服务器错误' });
});
// Fastify
app.setErrorHandler((error, request, reply) => {
request.log.error(error);
reply.status(500).send({ error: '服务器错误' });
});
// Step 4: 启动服务
// Express: app.listen(3000)
// Fastify: app.listen({ port: 3000 })08.总结
| 维度 | Express | Fastify |
|---|---|---|
| 性能 | 中等 | 极高 |
| 学习曲线 | 低 | 中等 |
| TypeScript | 需额外配置 | 原生支持 |
| 验证机制 | 手动/自定义 | JSON Schema |
| 生态成熟度 | 高 | 中等(快速增长) |
| 更新维护 | 较少 | 活跃 |
最终建议:如果是新项目且团队有一定 TypeScript 经验,直接选择 Fastify。如果是维护现有 Express 项目,或者需要快速开发小工具,Express 仍然是可靠的选择。两者都是经过大量生产验证的框架,选择哪个都不会有太大问题。