为什么选择 Fastify
高效的服务器意味着更低的基础设施成本、更好的负载响应能力和更愉快的用户体验。在尽可能处理最大数量的请求的同时,如何有效地管理服务器资源,同时不牺牲安全性验证和便捷的开发?
Fastify 应运而生。Fastify 是一个高度专注于提供最佳开发者体验、最低开销和强大插件架构的 Web 框架。它受到 Hapi 和 Express 的启发,据我们所知,它是目前速度最快的 Web 框架之一。
谁在使用 Fastify?
Fastify 自豪地为众多组织和产品提供支持。
核心特性
以下是 Fastify 建立的基础主要特性和原则
- 高性能:据我们所知,Fastify 是目前速度最快的 Web 框架之一,根据代码复杂度,每秒可以处理高达 30,000 个请求。
- 可扩展性:Fastify 通过其钩子、插件和装饰器完全可扩展。
- 基于 Schema:即使不是强制性的,我们也建议使用 JSON Schema 来验证您的路由并序列化输出,Fastify 内部会将 Schema 编译成高性能函数。
- 日志记录:日志非常重要,但成本很高;我们选择了最好的日志记录器来几乎消除此成本,Pino!
- 开发者友好:该框架旨在非常具有表现力,并在开发人员的日常使用中提供帮助,同时不牺牲性能和安全性。
- 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
请求/响应验证和钩子
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 附带一个类型文件,但您可能需要安装 @types/node
,具体取决于您使用的 Node.js 版本。
以下示例创建了一个 HTTP 服务器。
我们传递了我们使用的 HTTP 版本的相关类型。通过传递类型,我们可以正确地类型化访问路由中底层的 HTTP 对象。
如果使用 HTTP/2,我们将传递 <http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>
.
对于 HTTPS,请传递 http2.Http2SecureServer
或 http.SecureServer
而不是 Server。
这确保了在服务器处理程序中,我们也获得了 http.ServerResponse
,并在 reply.res
.
- 上具有正确的类型。
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()
TypeScript
插件
团队成员