• home > webfront > server > Fastify >

    Fastify 插件、装饰器、中间件、钩子

    Author:zhoulujun Date:

    在 Fastify 中,插件、装饰器、中间件和钩子是框架核心概念,各自承担不同的角色:插件(Plugins):插件是 Fastify 应用中用于添加功

    在 Fastify 中,插件、装饰器、中间件和钩子是框架核心概念,各自承担不同的角色:

    1. 插件(Plugins)

      • 插件是 Fastify 应用中用于添加功能、共享代码或封装逻辑的主要方式,可以说:在 JavaScript 中一切皆为对象,在 Fastify 中,一切都是插件 (plugin)。

      • 一个插件可以是一个函数,该函数接受 Fastify 实例、选项和回调函数作为参数。

      • 插件可以注册路由、添加装饰器、声明新的钩子,甚至可以封装其他插件,用于构建模块化的应用。

      • 插件允许开发者构建可重用的逻辑块,可以轻松地在不同的 Fastify 应用或同一个应用的不同部分之间共享。

    2. 装饰器(Decorators)

      • 装饰器在 Fastify 中用于扩展 Fastify 实例、请求(Request)和回复(Reply)对象,通过添加新的方法或属性。

      • 开发者可以使用装饰器来添加自定义的功能或数据,使其在整个应用的不同部分可用。

      • 例如,可以添加一个装饰器来添加一个方法,该方法在每个请求中都可用,用于访问共享的配置数据或服务。

    3. 中间件(Middleware)

      • 尽管 Fastify 设计上不依赖于中间件,但它支持使用 Express/Connect 风格的中间件,主要用于兼容性或特定功能的集成。

      • 中间件可以访问请求和响应对象,可以执行代码、修改请求和响应对象、终止请求处理链、调用堆栈中的下一个中间件等。

      • Fastify 中间件应谨慎使用,因为不当使用可能会绕过 Fastify 的一些优化,影响性能。

    4. 钩子(Hooks)

      • 钩子是 Fastify 中的一种机制,允许开发者在请求生命周期的不同阶段介入执行逻辑(例如,在请求接收之后、路由解析之前、发送响应之前等)。

      • 钩子可以用于执行一些预处理或后处理逻辑,如权限检查、请求日志记录、修改响应等。

      • Fastify 提供了多种类型的钩子(如 onRequest, preHandler, onSend, 等),使开发者能够精细控制请求处理的不同阶段。

    这些构件共同工作,为 Fastify 提供了极大的灵活性和扩展性,同时保持了框架的高性能特性。

    声明周期权重

    Fastify 中的组件(插件、装饰器、中间件和钩子)遵循一定的执行顺序和优先级,这些顺序和优先级定义了它们在请求处理流程中的作用时机。理解这个执行流程对于设计高效和可靠的 Fastify 应用至关重要。

    1. 插件插件在应用启动时加载,按照注册的顺序执行。一旦应用启动完成,插件的设置就被固化,对于后续的每个请求,插件中定义的功能(如路由、钩子、装饰器)都是可用的。

    2. 装饰器:装饰器本身没有明确的执行时机,它们提供的方法或属性在被装饰的对象(Fastify 实例、请求、回复)上即刻可用,并在对象的生命周期内持续有效。

    3. 中间件中间件在每个请求处理流程的早期执行,具体是在路由匹配之前。中间件可以修改请求和回复对象,或者决定是否将请求传递给下一个处理器。

    4. 钩子钩子遵循特定的执行顺序,反映在请求的处理流程中

      • 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 的一个基本特性是“封装上下文”。封装上下文决定了哪些装饰器、注册的钩子和插件可用于路由。

    注意,每个上下文仅从父上下文继承。父上下文不能访问其后代上下文中的任何实体。这种默认情况有时不是所需的。在这种情况下,可以通过使用 fastify-plugin 破坏封装上下文,使得在后代上下文中注册的任何东西都可用于包含的父上下文。



    参考文章:

    提升 Node.js 服务端性能:Fastify 框架 https://juejin.cn/post/7340109700767154228





    转载本站文章《Fastify 插件、装饰器、中间件、钩子》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/server/Fastify/9302.html