Nest.js请求的生命周期
请求生命周期
Nest 应用程序处理请求并按照我们所说的 请求生命周期 的顺序产生响应。使用中间件、管道、守卫和拦截器,在请求生命周期种追踪特定代码的执行位置可能会很困难,特别是当全局、控制器级和路由级组件开始发挥作用时。通常,一个请求通过中间件流到守卫,然后到拦截器,然后到管道,最后返回到返回路径上的拦截器(在生成响应时)。
Middleware(中间件)
中间件按特定顺序执行。首先,Nest 运行全局绑定的中间件(例如绑定的中间件),然后运行模块绑定的中间件,这些中间件是在路径上确定的 app.use 。中间件按照绑定的顺序按顺序运行,类似于 Express 中的中间件工作方式。对于跨不同模块绑定的中间件,绑定到根模块的中间件将首先运行,然后中间件将按照模块添加到 imports 数组的顺序运行。
Guards(守卫)
防护执行从全局防护开始,然后到控制器防护,最后到路由防护。与中间件一样,守卫按绑定顺序运行。例如:
1 | Guard1, Guard2) ( |
Guard1 将在之前 Guard2 执行,并且两者都将在 Guard3 之前执行。
Interceptors(拦截器)
在大多数情况下,拦截器遵循与守卫相同的模式,但有一个问题:当拦截器返回 RxJS Observables 时,可观察对象将以先进后出的方式解析。因此,入站请求将经过标准的全局、控制器、路由级解析,但请求的响应端(即从控制器方法处理程序返回后)将从路由到控制器再到全局进行解析。此外,管道、控制器或服务引发的任何错误都可以在拦截器的 catchError 运算符中读取。
Pipes(管道)
管道遵循标准的全局到控制器来路由绑定序列,在 @usePipes() 参数方面具有相同的先进先出顺序。但是,在路由参数级别,如果有多个管道在运行,则它们将按照最后一个参数的顺序运行,管道将运行到第一个参数。这也适用于路由级别和控制器级别管道。例如,如果我们有以下控制器:
1 | GeneralValidationPipe) ( |
然后 将 GeneralValidationPipe 运行 ,然后是 ,然后是 body 对象,然后移动到 RouteSpecificPipe query params ,遵循相同的顺序。如果有任何特定于参数的管道,它们将在控制器和路由级别管道之后运行(同样,从最后一个参数到第一个参数)。
Filters(过滤器)
筛选器是唯一不首先解析全局的组件。相反,过滤器从尽可能低的级别解析,这意味着执行从任何路由绑定过滤器开始,然后继续到控制器级别,最后到全局过滤器。请注意,异常不能从一个过滤器传递到另一个过滤器;如果路由级筛选器捕获异常,则控制器或全局级筛选器无法捕获相同的异常。实现此类效果的唯一方法是在筛选器之间使用继承。
总结
通常,请求的生命周期看起来如下所示:
1.传入请求
2.在全局范围内绑定的中间件
3.模块绑定中间件
4.全局警卫
5.控制器警卫
6.警卫路由
7.全局拦截器(零部件)
8.控制器拦截器(零部件)
9.路由拦截器(零部件)
10.全局管道
11.控制器的管道
12.路由管道
13.路由参数管道
14.控制器(方法处理程序)
15.服务(如果存在)
16.路由拦截器(post 请求)
17.控制器拦截器(post 请求)
18.全局拦截器(post 请求)
19.异常过滤器(路由,然后是控制器,然后是全局)
20.服务器响应