Fastify

中间件

Fastify 提供了一个开箱即用的异步中间件引擎。它兼容 ExpressRestify 的中间件。

想知道中间件何时执行,请看生命周期一文。

Fastify 的中间件不支持 middleware(err, req, res, next) 这一完整语法,因为错误在 Fastify 内部就被解决了。 此外,Express 和 Restify 添加在 reqres 对象之上的方法,Fastify 也不支持。

假如你使用一个打包了多个更小的中间件的中间件,例如 helmet,为了性能考虑,我们建议你使用单个模块:

  1. fastify.use(require('cors')())
  2. fastify.use(require('dns-prefetch-control')())
  3. fastify.use(require('frameguard')())
  4. fastify.use(require('hide-powered-by')())
  5. fastify.use(require('hsts')())
  6. fastify.use(require('ienoopen')())
  7. fastify.use(require('x-xss-protection')())

或者,在这个 helmet 的例子中,你可以使用针对 Fastify 和 helmet 的整合做了优化的 fastify-helmet 插件

  1. const fastify = require('fastify')()
  2. const helmet = require('fastify-helmet')
  3. fastify.register(helmet)

请记住,中间件能被封装。这就意味着你可以通过使用 register 来决定中间件该在何处运行,正如插件指南一文所述。

Fastify 中间件不会暴露 send 等 Fastify 的 Reply 实例上专属的方法。这是因为,虽然 Fastify 使用 RequestReply 对象包裹了 Node 原生的 reqres 实例,但是它们的处理要在中间件阶段之后。因此,在一个中间件里,你必须使用 Node 原生的 reqres 对象。要使用 Fastify 的 RequestReply 实例,你可以通过 preHandler 钩子。更多信息,请看钩子

将中间件限定在特定的路径执行

如果你只想在某些路径下运行一个中间件,只需将路径作为 use 的第一个参数传递即可!

注意,该做法不支持参数路由 (例如:/user/:id/comments),且在多个路径中不能使用通配符。

  1. const path = require('path')
  2. const serveStatic = require('serve-static')
  3. // 单个路径
  4. fastify.use('/css', serveStatic(path.join(__dirname, '/assets')))
  5. // 通配符路径
  6. fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets')))
  7. // 多个路径
  8. fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))

Express 中间件兼容性

Express 很大程度上修改了 Node 原生的 Request 和 Response 对象,所以 Fastify 无法确保中间件一定完全兼容。一些 Express 特殊的功能,例如 res.sendFile()res.send() 或者 express.Router() 的实例将无法在 Fastify 中正常工作。举个例子,cors 可以正常兼容但是 passport 就不可以。