这五个包都是 Node.js 生态中用于构建 Web 服务器和 API 的核心框架。express 是最经典的最小化框架;fastify 主打高性能和 schema 验证;koa 由 Express 原班人马打造,基于 async/await;hapi 侧重配置化和企业级安全(注意包名已变更);sails 则是全功能 MVC 框架,内置 ORM 和 WebSocket。
在 Node.js 后端开发中,选择合适的 Web 框架直接影响项目的性能、维护成本和开发体验。express、fastify、koa、hapi 和 sails 代表了五种不同的设计思路。本文将从架构设计、代码写法、性能验证和维护状态五个维度进行深度对比。
express 采用线性中间件模型。
// express: 线性中间件
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
fastify 采用插件化架构。
// fastify: 插件注册
fastify.register(async (instance) => {
instance.get('/route', (req, reply) => {
reply.send({ hello: 'world' });
});
});
koa 采用洋葱模型中间件。
await next() 控制流程。// koa: 洋葱模型
app.use(async (ctx, next) => {
console.log('Before');
await next();
console.log('After');
});
hapi 采用配置驱动架构。
// hapi: 配置路由
server.route({
method: 'GET',
path: '/',
options: {
handler: (request, h) => 'Hello'
}
});
sails 采用 MVC 全栈架构。
// sails: 控制器动作
module.exports = {
fn: async function (req, res) {
return res.ok('Hello');
}
};
处理请求数据的方式决定了代码的简洁度。
express 使用 req 和 res 对象。
// express: req/res 分离
app.get('/user', (req, res) => {
res.json({ id: req.query.id });
});
fastify 使用 req 和 reply 对象。
reply 对象提供链式调用。// fastify: req/reply 链式
fastify.get('/user', (req, reply) => {
return { id: req.query.id }; // 自动发送
});
koa 使用统一的 ctx 上下文。
ctx 上。// koa: ctx 统一上下文
app.use(async (ctx) => {
ctx.body = { id: ctx.query.id };
});
hapi 使用 request 和 h 响应工具。
h 对象提供响应构建方法。// hapi: request/h 工具
server.route({
method: 'GET',
path: '/user',
handler: (request, h) => {
return { id: request.query.id };
}
});
sails 使用 req 和 res 但封装在动作中。
res.ok, res.serverError 等 helper。// sails: 内置响应 helper
module.exports = {
fn: async function (req, res) {
return res.json({ id: req.param('id') });
}
};
express 默认无验证,需手动或引入库。
// express: 手动验证
app.post('/data', (req, res) => {
if (!req.body.email) return res.status(400).send('Missing');
res.send('OK');
});
fastify 内置 JSON Schema 验证。
// fastify: Schema 验证
fastify.post('/data', {
schema: {
body: {
type: 'object',
required: ['email'],
properties: { email: { type: 'string' } }
}
}
}, (req, reply) => {
reply.send('OK'); // 自动验证失败返回 400
});
koa 无内置验证,依赖中间件。
koa-bodyparser 等。// koa: 中间件验证
app.use(async (ctx, next) => {
if (!ctx.request.body.email) {
ctx.status = 400;
return;
}
await next();
});
hapi 内置强大验证库 (Joi)。
// hapi: Joi 验证配置
server.route({
method: 'POST',
path: '/data',
options: {
validate: {
payload: Joi.object({ email: Joi.string().required() })
},
handler: (request, h) => 'OK'
}
});
sails 内置 Waterline ORM 验证。
// sails: 模型层验证
// api/models/User.js
attributes: {
email: { type: 'string', required: true }
}
hapi 包名已变更。
hapi 包已弃用,新项目不应使用。@hapi/hapi scoped 包。sails 更新节奏较慢。
express, fastify, koa 均活跃维护。
express 进入稳定期,变化少。fastify 迭代快,性能持续优化。koa 保持稳定,适合现代语法偏好者。| 特性 | express | fastify | koa | hapi | sails |
|---|---|---|---|---|---|
| 架构模式 | 线性中间件 | 插件系统 | 洋葱模型 | 配置驱动 | MVC 全栈 |
| 请求对象 | req/res | req/reply | ctx | request/h | req/res |
| 数据验证 | 手动/第三方 | 内置 Schema | 中间件 | 内置 Joi | 内置 ORM |
| 性能表现 | 中等 | 极高 | 高 | 中等 | 较低 |
| 学习曲线 | 低 | 中 | 中 | 高 | 中 |
| 维护状态 | 活跃 | 活跃 | 活跃 | 活跃 (新包名) | 缓慢 |
express 是通用型选择 🧰。
fastify 是性能型选择 🚀。
koa 是现代化选择 🌱。
hapi 是规范型选择 📜。
@hapi/hapi 包。sails 是全栈型选择 🏗️。
没有绝对最好的框架,只有最适合场景的工具。如果你追求稳定和生态,选 express;追求性能和验证,选 fastify;追求现代语法,选 koa。对于 hapi,请确保使用新包名;对于 sails,请确认你需要的是全栈框架而非轻量 API 服务。
选择 express 如果你需要最广泛的社区支持和中间件生态,适合快速构建标准 API 或 SSR 服务。它的学习曲线平缓,文档丰富,几乎能找到任何问题的解决方案,是大多数项目的安全默认选项。
选择 koa 如果你偏好现代 async/await 语法,希望从零组装中间件而不受历史包袱限制。它比 Express 更轻量,没有内置中间件,适合喜欢完全控制请求流程的开发者。
选择 fastify 如果你关注高吞吐量和低延迟,且希望利用 JSON Schema 自动验证请求数据。它的插件架构清晰,性能优于传统框架,适合对响应速度有严格要求的微服务。
选择 hapi 如果你需要严格的企业级配置规范,但请注意新项目中应使用 @hapi/hapi 包而非旧的 hapi 包。它适合大型团队需要统一配置标准和强安全策略的场景。
选择 sails 如果你需要类似 Ruby on Rails 的全栈体验,内置 ORM 和 WebSocket 且不想手动配置。它适合快速构建数据驱动的传统 Web 应用,但在微服务架构中可能显得过重。
Fast, unopinionated, minimalist web framework for Node.js.
This project has a Code of Conduct.
import express from 'express'
const app = express()
app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000')
})
This is a Node.js module available through the npm registry.
Before installing, download and install Node.js. Node.js 18 or higher is required.
If this is a brand new project, make sure to create a package.json first with
the npm init command.
Installation is done using the
npm install command:
npm install express
Follow our installing guide for more information.
PROTIP Be sure to read the migration guide to v5
The quickest way to get started with express is to utilize the executable express(1) to generate an application as shown below:
Install the executable. The executable's major version will match Express's:
npm install -g express-generator@4
Create the app:
express /tmp/foo && cd /tmp/foo
Install dependencies:
npm install
Start the server:
npm start
View the website at: http://localhost:3000
The Express philosophy is to provide small, robust tooling for HTTP servers, making it a great solution for single page applications, websites, hybrids, or public HTTP APIs.
Express does not force you to use any specific ORM or template engine. With support for over 14 template engines via @ladjs/consolidate, you can quickly craft your perfect framework.
To view the examples, clone the Express repository:
git clone https://github.com/expressjs/express.git --depth 1 && cd express
Then install the dependencies:
npm install
Then run whichever example you want:
node examples/content-negotiation
The Express.js project welcomes all constructive contributions. Contributions take many forms, from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, triaging incoming pull requests and issues, and more!
See the Contributing Guide for more technical details on contributing.
If you discover a security vulnerability in Express, please see Security Policies and Procedures.
To run the test suite, first install the dependencies:
npm install
Then run npm test:
npm test
For information about the governance of the express.js project, see GOVERNANCE.md.
The original author of Express is TJ Holowaychuk