拦截器与中间件和Nest.js中的过滤器有什么区别?拦截器中间件异常过滤器

问题描述 投票:4回答:2

Nest.js框架中的拦截器,过滤器和中间件有什么区别?什么时候应该使用其中一个而不是另一个?

谢谢

node.js typescript nestjs
2个回答
15
投票

正如你已经暗示过你的问题,这三个都是非常相似的概念,在很多情况下很难决定并归结为你的偏好。但我可以概述一下这些差异:

Interceptors

拦截器可以在调用路由处理程序之前和之后访问响应/请求。

Registration

  • 直接在控制器类中使用@UseInterceptors()控制器或方法作用域
  • 全球与app.useGlobalInterceptors()main.ts

Examples

  • LoggingInterceptor:路由处理程序之前的请求以及之后的结果。 Meassure需要的时间。
  • ResultMapping:将null转换为[]或将结果包装在响应对象中:users - > {users: users}

Conclusion

我喜欢与中间件相比,注册更接近路由处理程序。但是有一些限制,例如你不能设置响应代码,当你在路由处理程序中使用response@Res()对象时,你不能使用拦截器。

Middleware

仅在调用路由处理程序之前调用中间件。您可以访问响应对象,但是您没有路由处理程序的结果。它们基本上是表达中间件功能。

Registration

  • 在模块中,选择相关路线的方式非常灵活(使用通配符,按方法,......)
  • 全球与app.use()main.ts

Examples

  • FrontendMiddleware:将除API之外的所有路由重定向到index.html,请参阅article
  • 您可以使用任何外部的快速中间件。有很多库,例如body-parsermorgan

Conclusion

中间件的注册非常灵活,例如:适用于所有路由而不是一个等等。但由于它们已在模块中注册,因此当您查看其方法时,您可能没有意识到它适用于您的控制器。你可以利用那里的所有快速中间件库也很棒。

Exception Filters

异常过滤器在路由处理程序之后和拦截器之后调用。它们是在响应消失之前进行更改的最后一个位置。

Registration

  • 直接在控制器类中使用@UseFilters()控制器或方法作用域
  • 在你的app.useGlobalFilters()全球main.ts

Examples

  • 未经授权的过滤:映射到用户易于理解的消息
  • NotFoundFilter:将未找到的所有路由(不是api的一部分)映射到index.html

Conclusion

异常过滤器的基本用例是提供可理解的错误消息(隐藏技术细节)。但也有其他创造性的使用方法:当您提供单页应用程序时,通常所有路由都应重定向到index.html,但API的路由除外。在这里,你可以重定向NotFoundException。有些人可能会发现这个聪明的人很讨厌。你的选择。 ;-)


So the execution order is:

中间件 - >拦截器 - >路由处理程序 - >拦截器 - >异常过滤器(如果抛出异常)

使用它们中的所有三个,您可以在其构造函数中注入其他依赖项(如服务,...)。


2
投票

我假设您的意思是管道而不是过滤器,因为过滤器主要与异常处理相关联。

肯定有一些重叠,因为中间件是一种灵活的组合任何Web应用程序的方式,但它更像是一个通用概念(创建一堆函数来构建管道)。其他是Nest特定的概念,因此更依赖于依赖注入等事物。

管道用于转换输入数据(并且可选地进行验证)。

拦截器非常简洁,因为它们可以转换进入和离开API的数据。它们使您能够通过使用可观察流来改变原始处理程序返回的内容。这可能是您可能需要使用两个中间件(在处理程序的任一侧)实现的。

如果要转换进入处理程序的数据,请使用管道。

需要双向转换时使用拦截器。

当您希望更接近传统(例如Express)构建Web应用程序的方式时,或者当您想要更广泛地将功能同时应用于许多处理程序时(在代码中浮动的装饰器较少),请使用中间件。

© www.soinside.com 2019 - 2024. All rights reserved.