繁体   English   中英

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

[英]What's the difference between Interceptor vs Middleware vs Filter in Nest.js?

Nest.js 框架中的拦截器、过滤器和中间件有什么区别? 什么时候应该使用其中一个并优先于另一个?

谢谢

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

拦截器

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

登记

  • 直接在具有@UseInterceptors()控制器或方法范围的控制器类中
  • 全局使用 main.ts 中的main.ts app.useGlobalInterceptors()

例子

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

结论

与中间件相比,我喜欢注册更接近路由处理程序。 但是有一些限制,例如,当您在路由处理程序中使用库特定的@Res()对象发送response时,您无法设置响应代码或使用拦截器更改响应,请参阅文档

中间件

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

登记

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

例子

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

结论

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

异常过滤器

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

登记

  • 直接在具有@UseFilters()控制器或方法范围的控制器类中
  • 全局app.useGlobalFilters()在你的main.ts

例子

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

结论

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


所以执行顺序是:

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

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

对于我们这些在视觉上“理解”得更好的人,我基于最新的v6.10版本创建了这个 NestJs 管道图。 请随时指出任何不准确之处。 如果需要,我会及时审查和更新它。

在此处输入图像描述

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

肯定有一些重叠,因为中间件是组合任何 Web 应用程序的灵活方式,但更多的是通用概念(创建一堆函数来构建管道)。 其他的是 Nest 特定的概念,因此更自然地与依赖注入之类的东西联系在一起。

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

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

当您想要转换进入处理程序的数据时,请使用管道。

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

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

中间件

Nest.js的中间件的用法和功能基本等同于Express.js,一般作用于:

  • 执行任何代码。
  • 更改请求和响应对象。
  • 结束请求-响应周期。
  • 调用堆栈中的下一个中间件函数。
  • 如果当前中间件函数没有结束请求-响应循环,它必须调用next()将控制权传递给下一个中间件函数。 否则,请求将被挂起。

拦截器

拦截器可以在控制器和客户端之间转换数据,它可以执行以下功能:

  • 在方法执行之前/之后绑定额外的逻辑
  • 转换从函数返回的结果
  • 转换函数抛出的异常
  • 扩展基本功能行为
  • 根据特定条件完全覆盖函数(例如,出于缓存目的)

筛选

在 Nest.js 中,Filter 一般指的是 Exception 过滤器,它负责处理跨应用程序的所有未处理的异常:

  • 内置的全局异常过滤器处理 HttpException 类型的异常(及其子类)
  • 自定义异常过滤器旨在控制精确的控制流和发送回客户端的响应内容。 例如,根据一些动态因素添加日志记录或使用不同的 JSON 模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM