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

谢谢

推荐答案

正如你在问题中已经暗示的那样,这三个概念都非常相似,在很多情况下很难决定,这取决于你的偏好.但我可以概述一下这些区别:

Interceptors

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

登记

  • 直接在控制器类中,控制器或方法作用域为@UseInterceptors()
  • 在全局,main.ts分之app.useGlobalInterceptors()

例子

  • LoggingInterceptor:在路由处理程序之前请求,然后请求结果.这需要一定的时间.
  • ResultMapping: Transform null to [] or wrap result in a response object: users -> {users: users}

结论

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

Middleware

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

登记

  • 在模块中, Select 相关路由的非常灵活的方式(使用通配符,通过方法,…)
  • 在全局,main.ts分之app.use()

例子

  • FrontendMiddleware:将除API之外的所有路由重定向到index.html,请参见this thread
  • 您可以使用任何存在的express中间件.图书馆共有lots个,例如body-parser个或morgan

结论

中间件的注册非常灵活,例如:应用于除一条以外的所有路由等.但由于它们在模块中注册,当您查看其方法时,您可能没有意识到它适用于您的控制器.还可以利用所有的express中间件库.

Exception Filters

异常过滤器在路由处理程序和拦截器之后调用.在做出回应之前,他们是最后一个做出改变的地方.

登记

  • 直接在控制器类中,控制器或方法作用域为@UseFilters()
  • 全球app.useGlobalFilters()

例子

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

结论

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


So the execution order is:

Middleware -> Interceptors -> Route Handler -> Interceptors -> Exception Filter (if exception is thrown)

使用这三种方法,您可以注入其他依赖项(如服务,…)在他们的构造器中.

Node.js相关问答推荐

MongoDB-如何验证Document字段以仅允许特定的文件扩展名?

即使DDB键不存在, node Lambda也不会失败,并返回NULL作为结果

编辑Mongoose中的对象嵌套数组

带有apache Couch-db和Nano的推荐引擎:过滤特定用户的视图

npm错误;无法解析依赖项:npm ERR!对等webpack@;5.x.x;来自@webpack-cli/serve@2.0.5";

如何修复node.js中的错误代码无法加载资源:服务器响应状态为403(禁止)

如何在 JavaScript 中显示多维数组中使用的一维数组的变量名?

使用 NPM 三个 mocha+typescript 进行测试

npm install 在 Mac 上的 Node-gyp 构建错误

如何在 NestJS 中使用外部生成的 swagger.json?

使用 .pipe(res) 向客户端发送音频不允许您搜索?

部署云功能 Firebase/Stripe 时出错

为什么我在生产环境中 deproy Next.js 示例项目时 CSS 不起作用?

Cypress net::ERR_EMPTY_RESPONSE 在真实服务器调用上

Ansible 将以什么用户身份运行我的命令?

如何在 Node.js 中逐字节读取二进制文件

在 Node.js 中的两个不同进程之间进行通信

判断一个数组中的每个元素是否都在第二个数组中

nodejs v10.3.0 的 gulp 任务问题:src\node_contextify.cc:629: Assertion `args[1]->IsString()' failed

Node.js:如何附加到正在运行的进程并使用控制台调试服务器?