Fastify,快速并且低开销的 web 框架,专为 Node.js 平台量身打造
为什么选择 Fastify?
高效的服务器意味着更低的基础设施成本、更好的负载响应能力和用户满意度。 在不牺牲安全验证和便捷开发的前提下,如何知道服务器正在处理尽可能多的请求,又如何有效地处理服务器资源?
用 Fastify 吧。Fastify 是一个 web 开发框架,其设计灵感来自 Hapi 和 Express,致力于以最少的开销和强大的插件结构提供最佳的开发体验。据我们所知,它是这个领域里速度最快的 web 框架之一。
核心功能
以下列出的是 Fastify 已经实现的主要功能及原理:
- 高性能: 据我们所知,Fastify 是这一领域中最快的 web 框架之一,另外,取决于代码的复杂性,Fastify 最多可以处理每秒 3 万次的请求。
- 可扩展: Fastify 通过其提供的钩子(hook)、插件和装饰器(decorator)提供完整的可扩展性。
- 基于 Schema: 即使这不是强制性的,我们仍建议使用 JSON Schema 来做路由(route)验证及输出内容的序列化,Fastify 在内部将 schema 编译为高效的函数并执行。
- 日志: 日志是非常重要且代价高昂的。我们选择了最好的日志记录程序来尽量消除这一成本,这就是 Pino!
- 对开发人员友好: 框架的使用很友好,帮助开发人员处理日常工作,并且不牺牲性能和安全性。
- 支持 TypeScript: 我们努力维护一个 TypeScript 类型声明文件,以便支持不断成长的 TypeScript 社区。
快速上手
通过 NPM 安装 fastify:
npm install fastify
然后创建 server.js
文件并输入如下内容:
// Require the framework and instantiate it
const fastify = require('fastify')({ logger: true })
// Declare a route
fastify.get('/', (request, reply) => {
reply.send({ hello: 'world' })
})
// Run the server!
fastify.listen(3000, (err) => {
if (err) {
fastify.log.error(err)
process.exit(1)
}
})
// Require the framework and instantiate it
const fastify = require('fastify')({ logger: true })
// Declare a route
fastify.get('/', async (request, reply) => {
return { hello: 'world' }
})
// Run the server!
const start = async () => {
try {
await fastify.listen(3000)
} catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()
最后,通过如下命令启动:
node server
测试地址:
curl http://localhost:3000
使用命令行工具(CLI)
利用 NPM 安装 fastify-cli:
npm install --global fastify-cli
然后利用以下命令创建一个新项目:
fastify generate myproject
请求/响应(Request/Response)验证和钩子(hooks)
当然,Fastify 能做的比这些更多。
例如,你可以使用 JSON Schema 轻松地提供输入和输出验证,并在执行处理程序之前执行特定操作:
const fastify = require('fastify')({ logger: true })
fastify.route({
method: 'GET',
url: '/',
schema: {
// request needs to have a querystring with a `name` parameter
querystring: {
name: { type: 'string' }
},
// the response needs to be an object with an `hello` property of type 'string'
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
},
// this function is executed for every request before the handler is executed
preHandler: (request, reply, done) => {
// E.g. check authentication
done()
},
handler: (request, reply) => {
reply.send({ hello: 'world' })
}
})
fastify.listen(3000, (err) => {
if (err) {
fastify.log.error(err)
process.exit(1)
}
})
const fastify = require('fastify')({ logger: true })
fastify.route({
method: 'GET',
url: '/',
schema: {
// request needs to have a querystring with a `name` parameter
querystring: {
name: { type: 'string' }
},
// the response needs to be an object with an `hello` property of type 'string'
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
},
// this function is executed for every request before the handler is executed
preHandler: async (request, reply) => {
// E.g. check authentication
},
handler: async (request, reply) => {
return { hello: 'world' }
}
})
const start = async () => {
try {
await fastify.listen(3000)
} catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()
支持 TypeScript
Fastify 附带了一个 typings 文件,因此你需要安装 @types/node
,具体取决于你所使用的 Node.js 版本。
以下示例创建了一个 http 服务。
我们向所使用的 http 版本传递相关的 typings。
在路由中,通过传递类型,我们可以获取到正确类型化的底层 http 对象。
如果使用的是 http2,需要传递 <http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>
。
对于 https,需要传递 http2.Http2SecureServer
或 http.SecureServer
而不是 Server。
这确保了在服务的处理程序中,我们还可以通过 reply.res
获取到具有正确 typings 的 http.ServerResponse
。
import Fastify, { FastifyInstance, RouteShorthandOptions } from 'fastify'
import { Server, IncomingMessage, ServerResponse } from 'http'
const server: FastifyInstance = Fastify({})
const opts: RouteShorthandOptions = {
schema: {
response: {
200: {
type: 'object',
properties: {
pong: {
type: 'string'
}
}
}
}
}
}
server.get('/ping', opts, (request, reply) => {
reply.send({ pong: 'it worked!' })
})
server.listen(3000, (err) => {
if (err) {
server.log.error(err)
process.exit(1)
}
const address = server.server.address()
const port = typeof address === 'string' ? address : address?.port
})
import Fastify, { FastifyInstance, RouteShorthandOptions } from 'fastify'
import { Server, IncomingMessage, ServerResponse } from 'http'
const server: FastifyInstance = Fastify({})
const opts: RouteShorthandOptions = {
schema: {
response: {
200: {
type: 'object',
properties: {
pong: {
type: 'string'
}
}
}
}
}
}
server.get('/ping', opts, async (request, reply) => {
return { pong: 'it worked!' }
})
const start = async () => {
try {
await server.listen(3000)
const address = server.server.address()
const port = typeof address === 'string' ? address : address?.port
} catch (err) {
server.log.error(err)
process.exit(1)
}
}
start()
请阅读 文档 并了解 Fastify 已经提供的更多功能。
一个速度快的 web 框架
基于我们在 Node.js 性能方面的经验,Fastify 从一开始就奔着 尽可能快 的目标来构建的。请查看一下我们的 基准测试章节 列出的 Fastify 与其它常见 web 框架之间的性能对比。
生态系统
Fastify 拥有一个不断增长的插件生态。你最喜欢的数据库或模板语言可能也已经有 Fastify 插件了。 请前往 生态系统页面 浏览当前可用的插件。 找不到你所需要的插件吗?小 case, 自己动手写一个也很容易!
开发组成员
按字母顺序排列