Fastify 插件、装饰器、中间件、钩子
Author:zhoulujun Date:
在 Fastify 中,插件、装饰器、中间件和钩子是框架核心概念,各自承担不同的角色:
插件(Plugins):
插件是 Fastify 应用中用于添加功能、共享代码或封装逻辑的主要方式,可以说:在 JavaScript 中一切皆为对象,在 Fastify 中,一切都是插件 (plugin)。
一个插件可以是一个函数,该函数接受 Fastify 实例、选项和回调函数作为参数。
插件可以注册路由、添加装饰器、声明新的钩子,甚至可以封装其他插件,用于构建模块化的应用。
插件允许开发者构建可重用的逻辑块,可以轻松地在不同的 Fastify 应用或同一个应用的不同部分之间共享。
装饰器(Decorators):
装饰器在 Fastify 中用于扩展 Fastify 实例、请求(Request)和回复(Reply)对象,通过添加新的方法或属性。
开发者可以使用装饰器来添加自定义的功能或数据,使其在整个应用的不同部分可用。
例如,可以添加一个装饰器来添加一个方法,该方法在每个请求中都可用,用于访问共享的配置数据或服务。
中间件(Middleware):
尽管 Fastify 设计上不依赖于中间件,但它支持使用 Express/Connect 风格的中间件,主要用于兼容性或特定功能的集成。
中间件可以访问请求和响应对象,可以执行代码、修改请求和响应对象、终止请求处理链、调用堆栈中的下一个中间件等。
Fastify 中间件应谨慎使用,因为不当使用可能会绕过 Fastify 的一些优化,影响性能。
钩子(Hooks):
钩子是 Fastify 中的一种机制,允许开发者在请求生命周期的不同阶段介入执行逻辑(例如,在请求接收之后、路由解析之前、发送响应之前等)。
钩子可以用于执行一些预处理或后处理逻辑,如权限检查、请求日志记录、修改响应等。
Fastify 提供了多种类型的钩子(如
onRequest
,preHandler
,onSend
, 等),使开发者能够精细控制请求处理的不同阶段。
这些构件共同工作,为 Fastify 提供了极大的灵活性和扩展性,同时保持了框架的高性能特性。
声明周期权重
Fastify 中的组件(插件、装饰器、中间件和钩子)遵循一定的执行顺序和优先级,这些顺序和优先级定义了它们在请求处理流程中的作用时机。理解这个执行流程对于设计高效和可靠的 Fastify 应用至关重要。
插件:插件在应用启动时加载,按照注册的顺序执行。一旦应用启动完成,插件的设置就被固化,对于后续的每个请求,插件中定义的功能(如路由、钩子、装饰器)都是可用的。
装饰器:装饰器本身没有明确的执行时机,它们提供的方法或属性在被装饰的对象(Fastify 实例、请求、回复)上即刻可用,并在对象的生命周期内持续有效。
中间件:中间件在每个请求处理流程的早期执行,具体是在路由匹配之前。中间件可以修改请求和回复对象,或者决定是否将请求传递给下一个处理器。
钩子:钩子遵循特定的执行顺序,反映在请求的处理流程中:
onRequest
:在请求被接收后立即执行,但在任何其他处理之前。preParsing
:在请求体解析之前执行。preValidation
:在路由级别的验证之前执行。preHandler
:在路由处理函数之前执行。preSerialization
:在响应被序列化之前执行,发送给客户端之前。onSend
:在响应发送给客户端之前,但在序列化之后执行。onResponse
:在响应完全发送给客户端后执行。钩子遵循特定的执行顺序,反映在请求的处理流程中:
针对中断的能力:
插件:不直接参与请求处理的中断,但可以注册会影响流程的钩子或中间件。
装饰器:不控制流程,因此不参与中断。
中间件:可以中断请求处理流程,例如,不调用
next()
或发送响应可以停止后续处理。钩子:特定的钩子(如
preHandler
)可以决定是否继续处理请求,或者直接发送响应,从而中断后续流程。
理解这些组件的执行顺序和中断能力对于构建符合预期行为的 Fastify 应用至关重要。
Incoming Request │ └─▶ Routing │ └─▶ Instance Logger │ 4**/5** ◀─┴─▶ onRequest Hook │ 4**/5** ◀─┴─▶ preParsing Hook │ 4**/5** ◀─┴─▶ Parsing │ 4**/5** ◀─┴─▶ preValidation Hook │ 400 ◀─┴─▶ Validation │ 4**/5** ◀─┴─▶ preHandler Hook │ 4**/5** ◀─┴─▶ User Handler │ └─▶ Reply │ 4**/5** ◀─┴─▶ preSerialization Hook │ └─▶ onSend Hook │ 4**/5** ◀─┴─▶ Outgoing Response │ └─▶ onResponse Hook
当响应被劫持时 (即调用了 reply.hijack()) 会跳过之后的步骤,否则,响应被提交后的数据流向如下:
★ schema validation Error │ └─▶ schemaErrorFormatter │ reply sent ◀── JSON ─┴─ Error instance │ │ ★ throw an Error ★ send or return │ │ │ │ │ │ ▼ │ reply sent ◀── JSON ─┴─ Error instance ──▶ setErrorHandler ◀─────┘ │ reply sent ◀── JSON ─┴─ Error instance ──▶ onError Hook │ └─▶ reply sent
封装
Fastify 的一个基本特性是“封装上下文”。封装上下文决定了哪些装饰器、注册的钩子和插件可用于路由。
注意,每个上下文仅从父上下文继承。父上下文不能访问其后代上下文中的任何实体。这种默认情况有时不是所需的。在这种情况下,可以通过使用 fastify-plugin 破坏封装上下文,使得在后代上下文中注册的任何东西都可用于包含的父上下文。
参考文章:
提升 Node.js 服务端性能:Fastify 框架 https://juejin.cn/post/7340109700767154228
转载本站文章《Fastify 插件、装饰器、中间件、钩子》,
请注明出处:https://www.zhoulujun.cn/html/webfront/server/Fastify/9302.html