网络请求流程
类型 | 声明方式 | 使用方式 | 接口或基类 | 实现名称 | 可访问对象 | 作用对象 |
中间件 | 类、函数 | 模块中组装 | NestMiddleware | use(requires,next) | Request/Response/Next | 路径(映射) |
异常过滤器 | 类 | 装饰器 | ExceptionFilter | catch(exception,host) | ArgumentsHost | 全局、控制器、方法 |
管道 | 类 | 装饰器 | PipeTransform | transform(value,metadata) | 参数以及参数元数据 | 全局、控制器、方法、参数 |
守卫 | 类 | 装饰器 | CanActivate | canActivate(context) | ExecutionContext | 全局、控制器、方法 |
拦截器 | 类 | 装饰器 | NestInterceptor | intercept(context,next) | ExecutionContext | ㅤ |
客户端请求 ---> 中间件 ---> 守卫 ---> 拦截器之前 ---> 管道 ---> 控制器处理并响应 ---> 拦截器之后 ---> 过滤器拦截器是在响应之前,响应之后执行。它常用功能就是打印响应日志,缓存数据,转化响应数据,响应超时判断。中间件是在请求结束就立即执行了,你说的兼容express也差不多,需要封装,不能直接使用。可以参考这里nest-middlewares。他们注册位置区别:
- 拦截器:controller的类和方法上面的装饰器
@UseInterceptors
,全局使用app.useGlobalInterceptors()
- 中间件: 中间件是模块里面注册的,然后对应路由
path和method
,全局使用app.use()
他们共同点是全局都不能使用依赖注入,只能在私有注册才能使用依赖注入,并且不能用new
实例化。根据我理解:请求到响应的生命周期
- 接收客户端发起请求
- 中间件去做请求处理,比如
helmet
,csrf
,rate limiting
,compression
等等常用的处理请求的中间件。
- 守卫就验证该用户的身份,如果没有权限或者没有登录,就直接抛出异常,最适合做权限管理。
- 拦截器根据作者解释,拦截器之前不能修改请求信息。只能获取请求信息。
- 管道做请求的数据验证和转化,如果验证失败抛出异常。
- 这里处理响应请求的业务,俗称
controller
,处理请求和服务桥梁,直接响应服务处理结果。
- 拦截器之后只能修改响应body数据。
- 最后走过滤器:如果前面任何位置发生抛出异常操作,都会直接走它。
合适的人做合适的事,nest
是把各种功能抽象出来,根据每个功能去做它该做的事情,这么便于管理和维护,不然还是回去写express
更简单。
那这样看来,中间件的功能,除了对请求对象进行modify,添加session,csrf等一些全局性东西,其他的拦截器都能实现并且更好维护
- 请求进入
- 中间件
- 2.1. 全局绑定的中间件
- 2.2. 模块绑定的中间件
- 守卫
- 3.1 全局守卫
- 3.2 控制器守卫
- 3.3 路由守卫
- 拦截器(控制器前)
- 4.1 全局拦截器
- 4.2 控制器拦截器
- 4.3 路由拦截器
- 管道
- 5.1 全局管道
- 5.2 控制器管道
- 5.3 路由管道
- 5.4 路由参数管道
- 控制器(方法处理程序)
- 服务(如果存在)
- 拦截器(请求后)
- 8.1 路由拦截器
- 8.2 控制器拦截器
- 8.3 全局拦截器
- 异常过滤器
- 9.1 路由过滤器
- 9.2 控制器过滤器
- 9.3 全局过滤器
- 服务器响应
Loading...