
| 类型 | 声明方式 | 使用方式 | 接口或基类 | 实现名称 | 可访问对象 | 作用对象 |
|---|---|---|---|---|---|---|
| 中间件 | 类、函数 | 模块中组装 | 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等一些全局性东西,其他的拦截器都能实现并且更好维护