NestJs 中间件拦截机制

827 阅读4分钟

NestJs 中间件拦截机制

🎄Hi~ 大家好,我是小鑫同学,资深 IT 从业者,InfoQ 的签约作者,擅长前端开发并在这一领域有多年的经验,致力于分享我在技术方面的见解和心得

🚀技术&代码分享

  • 我在 94Code 总结技术学习;
  • 我在 1024Code 在线编写代码;
  • 我在 掘金 分享技术文章;
  • 我在 Github 参与开源学习;

😇推荐几个好用的工具

进入正题

在 Nest 中,中间件是一个可重用的函数,它可以在请求和响应之间进行处理。你可以使用中间件来处理请求和响应之间的逻辑,例如身份验证、日志记录、错误处理等。

基础项目准备

推荐你来1024Code Fork 我的《Nest Middleware》 开始这次学习,如果你不习惯使用在线的IDE,那么可以将项目导出到本地运行~

认识 Middleware

中间件是在路由处理程序之前调用的函数。中间件函数可以访问请求和响应对象,以及应用程序请求响应周期中的next() 中间件函数。 next() 中间件函数通常由名为 next 的变量表示。

利用中间件可以用来实现通用(非业务)的功能,如:日志记录、授权处理等,下面通过案例一下学习 NestJs 中间件的使用。

在案例中准备了 UsersArticles 两个 Controller,并且安装配置了 Swagger 模块来辅助验证。通过配置编写的日志中间件和授权中间件来学习 Nest 中配置和使用中间件的方式。

创建 Middleware

依旧使用 Nest CLI 创建:

# 创建未分组中间件
nest g mi <middleware-name>

# 创建分组中间件
nest g mi <path>/<middleware-name>

Middleware 模型

Middleware 应该是一个由 @Injectable() 装饰的 Class,并且必须实现 NestMiddleware 接口,在use函数中可以拦截请求和响应对象,并通过next()决定程序是继续进行还是被挂起。

注册 Middleware

在实现 NestModule 接口的模块中通过注入 MiddlewareConsumer 模块得到注册中间件的能力。MiddlewareConsumer 提供了链式调用的方式,使用 apply() 函数注册指定的中间件模块,通过 forRouters() 函数控制中间件生效的路由、控制器、或HTTP动词,额外还可以通过使用 exclude() 来排除指定的请求。

消费者

注册单个中间件

使用 MiddlewareConsumer 提供的 apply() 函数注册指定的中间件模块。

下图中使用 apply()LoggerMiddleware 中间件注册,并在 users 路由下生效。

注册单个中间件

注册多个中间件

使用 MiddlewareConsumer 提供的 apply() 函数注册多个指定的中间件模块。

下图使用 apply()LoggerMiddlewareAuthMiddleware 中间件注册,并在 users 路由下生效。

注册多个中间件

指定 Controller

MiddlewareConsumer 提供的 forRouters() 不仅支持指定的路由,还支持指定 Controller 生效,下图中将配置 AuthMiddleware 仅在 Users 控制器下生效。

指定 Controller

指定 路由 + HTTP动词

同时 forRouters() 还支持在通过路由 + HTTP动词的方式生效,如下图配置的 LoggerMiddleware 则仅在通过 GET 请求 users 路由时生效。

指定 路由 + HTTP动词

排除 路由

MiddlewareConsumer 提供的 exclude() 函数可以在指定路由的情况下用来排除部分不需要生效的部分,下图配置在 users 生效后且排除了其中的 GET 和 POST 两种 HTTP 动词的请求。

排除 路由

更多中间件

当中间件没有成员、没有额外的依赖也没有依赖其他的中间件时,可以采用函数的形式定义为功能中间件。

功能中间件

当中间件需要在全局范围均生效的情况下,可以将中间件注册到 INestApplication 实例,称为全局中间件。

总结

以上就是 Nest 中 中间件的相关知识,它提供的中间件机制可以方便对于请求和响应对象的拦截修改,同时支持不同颗粒度的配置,更多的使用场景及中间件的应用就留在实战中实现吧。


如果看完觉得有收获,欢迎点赞、评论、分享支持一下。你的支持和肯定,是我坚持写作的动力~