express、hapi、koa 和 sails 都是 Node.js 生态中成熟的 Web 服务器框架,但设计哲学差异巨大。express 是最流行的极简框架,依靠中间件构建功能;koa 由 Express 原班人马打造,主打异步编程体验;hapi 强调配置驱动和安全性,适合大型企业;sails 则是全能型 MVC 框架,内置 ORM 和自动生成 API 功能。
对于前端架构师而言,选择 Node.js Web 框架不仅仅是选一个工具,而是选择一种开发模式和维护策略。express、hapi、koa 和 sails 代表了四种不同的设计思路。我们将通过核心架构、异步处理、路由验证和维护状态四个维度进行深度剖析。
express 采用线性中间件模型。
// express: 中间件链
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
app.get('/', (req, res) => {
res.send('Hello World');
});
hapi 采用配置驱动模型。
// hapi: 配置路由
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({ port: 3000 });
server.route({
method: 'GET',
path: '/',
handler: (request, h) => {
return 'Hello World';
}
});
await server.start();
};
koa 采用洋葱模型中间件。
ctx 封装了请求和响应,更简洁。// koa: 洋葱模型
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) => {
console.log('Time:', Date.now());
await next();
});
app.use(async ctx => {
ctx.body = 'Hello World';
});
sails 采用传统 MVC 架构。
// sails: 控制器动作
// api/controllers/HomeController.js
module.exports = {
index: function (req, res) {
return res.view('homepage', { message: 'Hello World' });
}
};
express 传统上基于回调,现在支持 Promise。
next() 函数传递控制流。next(err)。// express: 回调风格
app.get('/user', (req, res, next) => {
getUser(id, (err, user) => {
if (err) return next(err);
res.json(user);
});
});
hapi 原生支持 Promise 和 async/await。
// hapi: Promise 风格
server.route({
method: 'GET',
path: '/user',
handler: async (request, h) => {
const user = await getUser(id);
return user;
}
});
koa 原生基于 async/await 设计。
// koa: Async/Await 风格
app.use(async ctx => {
try {
const user = await getUser(id);
ctx.body = user;
} catch (err) {
ctx.status = 500;
}
});
sails 混合支持回调和 Promise。
// sails: 混合风格
// api/controllers/UserController.js
module.exports = {
find: async function (req, res) {
try {
const users = await User.find();
return res.json(users);
} catch (err) {
return res.serverError(err);
}
}
};
express 路由灵活,验证需第三方库。
express-router 或直接在 app 定义。joi 或 express-validator。// express: 灵活路由
app.use('/api', apiRouter);
// 验证需手动集成
app.post('/user', validateUser, (req, res) => {
res.send('Created');
});
hapi 内置强大的验证系统。
joi 库定义输入输出规则。// hapi: 内置验证
server.route({
method: 'POST',
path: '/user',
options: {
validate: {
payload: {
name: Joi.string().required()
}
}
},
handler: (request, h) => {
return { id: 1, name: request.payload.name };
}
});
koa 路由需中间件,验证需自行集成。
koa-router。// koa: 中间件路由
const router = require('koa-router')();
router.post('/user', async ctx => {
// 验证需手动调用
await validate(ctx.request.body);
ctx.body = 'Created';
});
app.use(router.routes());
sails 自动基于控制器生成路由。
// sails: 自动路由
// 配置 config/routes.js 或直接依赖约定
// GET /user/find 自动映射到 UserController.find
express 生态最庞大,更新稳定。
// express: 丰富的中间件生态
const cors = require('cors');
const helmet = require('helmet');
app.use(cors());
app.use(helmet());
hapi 企业级维护,更新节奏稳健。
// hapi: 插件注册
await server.register({
plugin: require('@hapi/inert') // 静态文件服务
});
koa 社区活跃,核心精简。
// koa: 组合中间件
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
sails 更新频率较低,生态增长缓慢。
// sails: 内置功能无需额外包
// WebSocket 支持默认开启,无需额外配置 socket.io
| 特性 | express | hapi | koa | sails |
|---|---|---|---|---|
| 架构模式 | 中间件链 | 配置驱动 | 洋葱模型 | MVC 框架 |
| 异步风格 | 回调/Promise | Promise/Async | Async/Await | 混合 |
| 路由方式 | 手动定义 | 配置对象 | 中间件 | 自动约定 |
| 数据验证 | 第三方库 | 内置 (Joi) | 第三方库 | 内置 |
| 学习曲线 | 低 | 中 | 中 | 高 |
| 适用场景 | 通用 API/SSR | 大型企业服务 | 高性能中间层 | 快速原型/旧项目 |
express 是默认的安全选择 🛡️。如果你不确定选什么,或者需要最多的社区资源,选它。它就像瑞士军刀,虽然不专精某一项,但什么都能做。
hapi 是严谨的工程师之选 📐。如果你需要严格的输入验证和配置管理,且团队规模较大,它能减少人为错误。
koa 是现代开发者的偏好 🚀。如果你讨厌回调地狱,希望代码更干净,且愿意自己组装工具,它提供更好的开发体验。
sails 是特定场景的利器 🔨。如果你需要快速生成完整的 CRUD API 且不想配置 ORM,它很快。但在新项目中,请仔细评估其长期维护性。
最后建议:对于大多数前端团队构建 BFF (Backend For Frontend) 或 SSR 服务,express 或 koa 通常是最优解。若涉及复杂的企业级业务逻辑且对安全性要求极高,hapi 值得考虑。避免在新的高并发核心业务中使用 sails,除非你有明确的遗留系统迁移需求。
选择 express 如果你需要最广泛的社区支持、丰富的中间件生态以及灵活的架构。它适合大多数 API 服务和 SSR 应用,尤其是团队希望快速上手且不受严格约束的场景。
选择 koa 如果你希望拥有更现代的异步编程体验(async/await),且喜欢极简核心以便自行组装工具链。它适合追求代码简洁性和高性能的中间层服务。
选择 hapi 如果你正在构建大型企业级应用,需要严格的输入验证、内置缓存策略和配置驱动的开发模式。它适合对安全性和稳定性要求极高的金融或数据敏感型项目。
选择 sails 如果你需要快速构建传统 MVC 结构的应用,且希望内置 ORM 和 WebSocket 支持而不想配置太多工具。但需注意其更新频率较低,适合维护旧项目或快速原型。
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