Nest.js框架中的拦截器,过滤器和中间件有什么区别?什么时候应该使用它们中的一个并使其比另一个更受青睐?
谢谢
答案 0 :(得分:11)
正如您已经暗示的问题一样,这三个概念都是非常相似的,在很多情况下,很难决定并取决于您的偏好。但我可以概述一下这些差异:
拦截器可以在之前和在调用路由处理程序之后访问响应/请求。
@UseInterceptors()
控制器或方法范围的app.useGlobalInterceptors()
中的main.ts
全局null
转换为[]
或将结果包装在响应对象中:users
-> {users: users}
我喜欢与中间件相比,注册更靠近路由处理程序。但是存在一些限制,例如,当在路由处理程序中将response
与@Res()
对象一起使用时,您将无法设置响应代码,也无法使用拦截器。
仅在调用路由处理程序之前调用中间件。您可以访问响应对象,但没有路由处理程序的结果。它们基本上是表达的中间件功能。
app.use()
中的main.ts
全局index.html
,请参阅article body-parser
或morgan
中间件的注册非常灵活,例如:应用于除一条路径之外的所有路由。但是,由于它们已在模块中注册,因此当您查看其方法时,您可能不会意识到它适用于您的控制器。可以利用现有的所有快速中间件库也很棒。
异常过滤器在路由处理程序和拦截器之后调用。它们是在响应消失之前最后进行更改的地方。
@UseFilters()
控制器或方法范围的app.useGlobalFilters()
中全局main.ts
index.html
。异常过滤器的基本用例提供了可以理解的错误消息(隐藏技术细节)。但是,还有其他创造性的使用方式:当您为单个页面应用程序提供服务时,通常,所有路径都应重定向到index.html
,API路径除外。在这里,您可以在NotFoundException
上重定向。有些人可能会发现这个聪明的人很hacky。你的选择。 ;-)
中间件->拦截器->路由处理程序->拦截器->异常过滤器(如果引发异常)
使用这三个函数,您可以在其构造函数中注入其他依赖项(例如服务,...)。
答案 1 :(得分:4)
答案 2 :(得分:2)
我假设您的意思是管道而不是过滤器,因为过滤器主要与异常处理相关。
由于中间件是组成任何Web应用程序的灵活方式,但肯定有一些重叠,但更多地是通用概念(创建功能栈以构建管道)。其他的则是Nest特定的概念,因此与诸如Dependency Injection之类的关系更加自然。
管道用于转换输入数据(并可选地进行验证)。
拦截器真的很整洁,因为它们可以转换进出API的数据。它们使您能够通过使用可观察的流来改变原始处理程序将返回的内容。这可能是您需要使用两个中间件(在处理程序的两侧)实现的。
当您要转换传入处理程序的数据时,请使用管道。
当需要双向转换时,请使用拦截器。
当您想要更接近于传统的(例如Express)构建Web应用程序的方式时,或者当您想一次将功能广泛地应用于许多处理程序时(使用更少的装饰器在代码中浮动),请使用中间件。 / p>