为什么选择 Fastify?
An efficient server implies a lower cost of the infrastructure, better responsiveness under load, and happy users. How can you efficiently handle the resources of your server, knowing that you are serving the highest number of requests possible, without sacrificing security validations and handy development?
那就使用 Fastify 吧。Fastify 是一个 web 开发框架,致力于以最少的开销和强大的插件结构 提供最佳的开发体验。其设计灵感来自 Hapi 和 Express, 据我们所知,它是这个领域里速度最快的 web 框架之一。
谁在用 Fastify ?
Fastify is proudly powering a large ecosystem of organizations and products out there with over 10 million downloads per month. Checkout our affiliate companies.
核心亮点
These are the main features and principles on which Fastify has been built:
- 高性能: 据我们所知,Fastify 是这一领域中最快的 web 框架之一, 另外,取决于代码的复杂性,Fastify 最多可以处理每秒 3 万次的请求。
- Extensible: Fastify is fully extensible via its hooks, plugins, and decorators.
- Schema-based: even if it is not mandatory we recommend using JSON Schema to validate your routes and serialize your outputs. Internally Fastify compiles the schema in a highly performant function.
- 日志: 日志是非常重要且代价高昂的。我们选择了最好的日志记录程序来, 尽量消除这一成本,这就是Pino!
- Developer friendly: the framework is built to be very expressive and help developers in their daily use, without sacrificing performance and security.
- 支持 TypeScript: 我们努力维护着一个 TypeScript 类型声明文件,以便支持不断 成长的 TypeScript 社区。
快速入门
通过 NPM 安装 Fastify:
npm install fastify
然后创建一个名为 server.js 的文件并输入如下内容:
- ESM
- CJS
// Import the framework and instantiate it
import Fastify from 'fastify'
const fastify = Fastify({
logger: true
})
// Declare a route
fastify.get('/', async function handler (request, reply) {
return { hello: 'world' }
})
// Run the server!
try {
await fastify.listen({ port: 3000 })
} catch (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('/', function handler (request, reply) {
reply.send({ hello: 'world' })
})
// Run the server!
fastify.listen({ port: 3000 }, (err) => {
if (err) {
fastify.log.error(err)
process.exit(1)
}
})
最后,通过如下命令启动服务:
node server
测试地址:
curl http://localhost:3000
使用命令行工具(CLI)
安装 fastify-cli 来创建一个新的脚手架项目:
npm install --global fastify-cli
fastify generate myproject或者创建一个 TypeScript 项目:
fastify generate myproject --lang=ts
请求/响应(Request/Response)的验证和钩子(hooks)
当然,Fastify 能做的比这些更多。例如, 你可以使用 JSON Schema 轻松地提供输入和输出验证, 并在执行处理程序之前执行特定操作:
- ESM
- CJS
import Fastify from 'fastify'
const fastify = Fastify({
logger: true
})
fastify.route({
method: 'GET',
url: '/',
schema: {
// request needs to have a querystring with a `name` parameter
querystring: {
type: 'object',
properties: {
name: { type: 'string'}
},
required: ['name'],
},
// 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' }
}
})
try {
await fastify.listen({ port: 3000 })
} catch (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: {
type: 'object',
properties: {
name: { type: 'string'}
},
required: ['name'],
},
// 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({ port: 3000 }, (err) => {
if (err) {
fastify.log.error(err)
process.exit(1)
}
})
支 持 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。
- TypeScript
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({ port: 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 has an ever-growing ecosystem of plugins. There is probably already a plugin for your favorite database or template language. Have a look at the Ecosystem page to navigate through the currently available plugins. Can't you find the plugin you are looking for? No problem, it's very easy to write one!
开发团队
按字母顺序
Collaborators
Acknowledgments
This project is kindly sponsored by:
Past Sponsors:
Also thanks to:
