express vs koa vs fastify vs hapi vs sails
Node.js Web 框架架构对比与选型指南
expresskoafastifyhapisails

Node.js Web 框架架构对比与选型指南

这五个包都是 Node.js 生态中用于构建 Web 服务器和 API 的核心框架。express 是最经典的最小化框架;fastify 主打高性能和 schema 验证;koa 由 Express 原班人马打造,基于 async/await;hapi 侧重配置化和企业级安全(注意包名已变更);sails 则是全功能 MVC 框架,内置 ORM 和 WebSocket。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
express72,770,92168,88075.4 kB1893 个月前MIT
koa5,636,03535,74865 kB2817 天前MIT
fastify4,762,01335,8212.77 MB1097 天前MIT
hapi57,86014,783-587 年前BSD-3-Clause
sails29,79922,8433.27 MB58925 天前MIT

Node.js Web 框架深度对比:Express, Fastify, Koa, Hapi 与 Sails

在 Node.js 后端开发中,选择合适的 Web 框架直接影响项目的性能、维护成本和开发体验。expressfastifykoahapisails 代表了五种不同的设计思路。本文将从架构设计、代码写法、性能验证和维护状态五个维度进行深度对比。

🏗️ 核心架构:中间件 vs 插件 vs MVC

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 全栈架构。

  • 内置控制器、模型、视图和路由。
  • 约定优于配置,适合传统 Web 应用。
// sails: 控制器动作
module.exports = {
  fn: async function (req, res) {
    return res.ok('Hello');
  }
};

📝 请求与响应处理:对象与上下文

处理请求数据的方式决定了代码的简洁度。

express 使用 reqres 对象。

  • 分离明确,但需要手动发送响应。
  • 社区中间件最丰富。
// express:  req/res 分离
app.get('/user', (req, res) => {
  res.json({ id: req.query.id });
});

fastify 使用 reqreply 对象。

  • reply 对象提供链式调用。
  • 默认自动序列化 JSON,性能更高。
// 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 使用 requesth 响应工具。

  • h 对象提供响应构建方法。
  • 结构严谨,适合复杂验证。
// hapi: request/h 工具
server.route({
  method: 'GET',
  path: '/user',
  handler: (request, h) => {
    return { id: request.query.id };
  }
});

sails 使用 reqres 但封装在动作中。

  • 内置 res.ok, res.serverError 等 helper。
  • 简化了常见响应场景。
// sails: 内置响应 helper
module.exports = {
  fn: async function (req, res) {
    return res.json({ id: req.param('id') });
  }
};

🛡️ 验证与性能:手动 vs 自动

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)。

  • 配置化验证,代码清晰。
  • 性能略低于 Fastify,但安全性高。
// 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 保持稳定,适合现代语法偏好者。

📊 核心特性对比表

特性expressfastifykoahapisails
架构模式线性中间件插件系统洋葱模型配置驱动MVC 全栈
请求对象req/resreq/replyctxrequest/hreq/res
数据验证手动/第三方内置 Schema中间件内置 Joi内置 ORM
性能表现中等极高中等较低
学习曲线
维护状态活跃活跃活跃活跃 (新包名)缓慢

💡 选型建议

express 是通用型选择 🧰。

  • 适合大多数 API 服务和 SSR 应用。
  • 遇到问题容易找到答案,生态最成熟。

fastify 是性能型选择 🚀。

  • 适合高并发微服务和对延迟敏感的系统。
  • 内置验证减少了样板代码,开发效率高。

koa 是现代化选择 🌱。

  • 适合喜欢 async/await 和轻量级的团队。
  • 没有历史包袱,代码更干净。

hapi 是规范型选择 📜。

  • 适合大型企业需要严格配置标准的场景。
  • 注意必须使用 @hapi/hapi 包。

sails 是全栈型选择 🏗️。

  • 适合快速构建数据驱动的传统 Web 应用。
  • 内置功能多,但灵活性不如微框架。

总结

没有绝对最好的框架,只有最适合场景的工具。如果你追求稳定和生态,选 express;追求性能和验证,选 fastify;追求现代语法,选 koa。对于 hapi,请确保使用新包名;对于 sails,请确认你需要的是全栈框架而非轻量 API 服务。

如何选择: express vs koa vs fastify vs hapi vs sails

  • express:

    选择 express 如果你需要最广泛的社区支持和中间件生态,适合快速构建标准 API 或 SSR 服务。它的学习曲线平缓,文档丰富,几乎能找到任何问题的解决方案,是大多数项目的安全默认选项。

  • koa:

    选择 koa 如果你偏好现代 async/await 语法,希望从零组装中间件而不受历史包袱限制。它比 Express 更轻量,没有内置中间件,适合喜欢完全控制请求流程的开发者。

  • fastify:

    选择 fastify 如果你关注高吞吐量和低延迟,且希望利用 JSON Schema 自动验证请求数据。它的插件架构清晰,性能优于传统框架,适合对响应速度有严格要求的微服务。

  • hapi:

    选择 hapi 如果你需要严格的企业级配置规范,但请注意新项目中应使用 @hapi/hapi 包而非旧的 hapi 包。它适合大型团队需要统一配置标准和强安全策略的场景。

  • sails:

    选择 sails 如果你需要类似 Ruby on Rails 的全栈体验,内置 ORM 和 WebSocket 且不想手动配置。它适合快速构建数据驱动的传统 Web 应用,但在微服务架构中可能显得过重。

express的README

Express Logo

Fast, unopinionated, minimalist web framework for Node.js.

This project has a Code of Conduct.

Table of contents

NPM Version NPM Downloads Linux Build Test Coverage OpenSSF Scorecard Badge

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')
})

Installation

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.

Features

  • Robust routing
  • Focus on high performance
  • Super-high test coverage
  • HTTP helpers (redirection, caching, etc)
  • View system supporting 14+ template engines
  • Content negotiation
  • Executable for generating applications quickly

Docs & Community

PROTIP Be sure to read the migration guide to v5

Quick Start

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

Philosophy

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.

Examples

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

Contributing

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.

Security Issues

If you discover a security vulnerability in Express, please see Security Policies and Procedures.

Running Tests

To run the test suite, first install the dependencies:

npm install

Then run npm test:

npm test

Current project team members

For information about the governance of the express.js project, see GOVERNANCE.md.

The original author of Express is TJ Holowaychuk

List of all contributors

TC (Technical Committee)

TC emeriti members

TC emeriti members

Triagers

Triagers emeriti members

Emeritus Triagers

License

MIT