@ fastify/ 表达
此插件添加了全部内容 快递 兼容以快取,它会暴露相同的 use 它允许您使用任何快取的中间软件或应用程序.
| 说明 | 此插件不应作为长期解决方案使用,它旨在帮助您实现从快递到快递的平稳过渡,但您应该随时间推移迁移出快递的具体代码来快递. |
| 自兹 Express 不支持 Node.js 核心 HTTP/2 模块,此插件也不支持 HTTP/2 . |
安装
npm i @fastify/express
兼容性
| 插件版本 | 快速化版本 |
|---|---|
>=4.x | ^5.x |
>=2.x <4.x | ^4.x |
^1.x | ^3.x |
^0.x | ^2.x |
请注意,如果一个快取版本没有支持,那么该插件的相应版本也一样 上表列出. 见 快速化 LTS 政策 更多细节.
使用量
注册插件并开始使用您的快递中间软件 .
const Fastify = require('fastify')
async function build () {
const fastify = Fastify()
await fastify.register(require('@fastify/express'))
// do you know we also have cors support?
// https://github.com/fastify/fastify-cors
fastify.use(require('cors')())
// express.Application is also accessible
fastify.express.disabled('x-powered-by') // true
return fastify
}
build()
.then(fastify => fastify.listen({ port: 3000 }))
.catch(console.log)
添加完整的应用程序
您可以注册整个快递申请,并与快递合作。 记住, @fastify/express 刚刚 express 盖子下需要同样的身体解析器 express。 。 。 .
// index.js
const fastify = require('fastify')()
const express = require('express')
const router = express.Router()
router.use(function (req, res, next) {
res.setHeader('x-custom', true)
next()
})
router.get('/hello', (req, res) => {
res.status(201)
res.json({ hello: 'world' })
})
router.get('/foo', (req, res) => {
res.status(400)
res.json({ foo: 'bar' })
})
router.patch('/bar', (req, res) => {
if (!req.body || Object.keys(req.body).length === 0) {
res.status(400)
res.json({ msg: 'no req.body'})
} else {
res.status(200)
res.json(req.body)
}
})
router.use('*', (req, res) => {
res.status(404)
res.json({ msg: 'not found'})
})
fastify.register(require('@fastify/express'))
.after(() => {
fastify.use(express.urlencoded({extended: false})) // for Postman x-www-form-urlencoded
fastify.use(express.json())
fastify.use(router)
})
fastify.listen({ port: 3000 }, console.log)
测试您的应用程序
运行 node index.js 启动您的服务器。 然后运行以下命令以确保您的服务器正常工作 。 使用可选 -v 为动词输出而用卷起的旗帜.
me@computer ~ % curl -X GET http://localhost:3000/hello
{"hello":"world"}%
me@computer ~ % curl -X GET http://localhost:3000/foo
{"foo":"bar"}%
me@computer ~ % curl -X GET http://localhost:3000/bar
{"msg":"not found"}%
me@computer ~ % curl -X PATCH -H 'content-type:application/json' http://localhost:3000/bar
{"msg":"no req.body"}%
me@computer ~ % curl -X PATCH -H 'content-type:application/json' -d '{"foo2":"bar2"}' http://localhost:3000/bar
{"foo2":"bar2"}%
封装支持
封装与Fastify一样有效,您可以在子系统中注册插件,您的快取代码将只在里面工作,或者您可以宣布快取插件顶级并注册到嵌入插件中的中件,而中件将只针对特定插件的嵌入路线执行.
在自己的子系统中注册插件 :
const fastify = require('fastify')()
fastify.register(subsystem)
async function subsystem (fastify, opts) {
await fastify.register(require('@fastify/express'))
fastify.use(require('cors')())
}
在特定插件中注册中间软件 :
const fastify = require('fastify')()
fastify
.register(require('@fastify/express'))
.register(subsystem)
async function subsystem (fastify, opts) {
fastify.use(require('cors')())
}
钩子和中间软件
每个已注册的中间软件将在 onRequest 钩相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.
看看这个 生命周期 要更好地了解每个请求是如何执行的.
const fastify = require('fastify')()
fastify
.register(require('@fastify/express'))
.register(subsystem)
async function subsystem (fastify, opts) {
fastify.addHook('onRequest', async (req, reply) => {
console.log('first')
})
fastify.use((req, res, next) => {
console.log('second')
next()
})
fastify.addHook('onRequest', async (req, reply) => {
console.log('third')
})
}
将中间软件执行限制为特定路径
如果您只需要在特定路径下运行一个中间软件, 只需通过路径作为第一个使用参数即可 !
const fastify = require('fastify')()
const path = require('node:path')
const serveStatic = require('serve-static')
fastify
.register(require('@fastify/express'))
.register(subsystem)
async function subsystem (fastify, opts) {
// Single path
fastify.use('/css', serveStatic(path.join(__dirname, '/assets')))
// Wildcard path
fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets')))
// Multiple paths
fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))
}
说明: 在前缀插件中,
@fastify/express重写字符串、阵列和 RegExp 挂载路径包含前缀 。 RegExp 路径^内有锚 团体(例如,/(?:^\/a|^\/b)/)不正确重写。 使用数组路径 相反:fastify.use(['/a', '/b'], middleware)。 。 。 .
在代理服务器中环绕快取
可以通过通过将 Express 请求对象包入代理服务器 createProxyHandler 函数生成代理处理器。 该函数将接收快取请求对象作为第一个参数.
例如,利用代理机将快取请求中的内容暴露出快取请求.
fastify.decorateRequest('welcomeMessage', 'Hello World');
fastify.register(expressPlugin, {
createProxyHandler: fastifyRequest => ({
get (target, prop) {
if (prop === 'welcomeMessage') {
return fastifyRequest[prop]
}
return target[prop]
}
})
})
类型脚本支持
要使用带有 TypeScript 的模块, 请确保安装 @types/express。 。 。 .
您需要添加 "types": ["@fastify/express"] 到您的 tsconfig.json 文件使用时 require 以导入插件.
中间软件替代品
Fastify为最常用的中间软件提供了一些替代品:
| 表达式中件 | 快捷插件 |
|---|---|
helmet | @fastify/helmet |
cors | @fastify/cors |
serve-static | @fastify/static |
解决问题
POST 请求与身体挂起
车体参数 库与 fastify-express,当你有 fastify 路线和任何 express 中间软件.
任何 POST 请求 机构,哪个 body-parser 会尝试分析,会挂断.
示例应用程序 :
const Fastify = require('fastify')
const Express = require('express')
const expressPlugin = require('@fastify/express')
const bodyParser = require('body-parser')
const fastify = Fastify()
const express = Express()
express.use(bodyParser.urlencoded({ extended: false }))
await fastify.register(expressPlugin)
fastify.use(express)
// this route will never reply
fastify.post('/hello', (req, reply) => {
return { hello: 'world' }
})
对于这个案子,你需要删除 body-parser,安装 @fastify/formbody 更改 @fastify/express 选项:
const Fastify = require('fastify')
const Express = require('express')
const expressPlugin = require('@fastify/express')
const fastifyFormBody = require('@fastify/formbody')
const fastify = Fastify()
const express = Express()
await fastify.register(fastifyFormBody)
await fastify.register(expressPlugin, {
// run express after `@fastify/formbody` logic
expressHook: 'preHandler'
})
fastify.use(express)
// it works!
fastify.post('/hello', (req, reply) => {
return { hello: 'world' }
})
许可证
许可证根据 麻省理工学院。 。 。 .
express 许可证