一、关于 NestJS 中间件

  • 通俗的讲:中间件就是匹配路由之前或者匹配路由完成做的一系列的操作。中间件中如果想往下 匹配的话,那么需要写 next()

image.png

  • NestJS 的中间件实际上等价于 express 中间件。 下面是 Express 官方文档中所述的中间件功能:
  • NestJS 中间件可以是一个函数,也可以是一个带有 @Injectable() 装饰器的类

    1. // 中间件函数可以执行以下任务:
    2. 执行任何代码。
    3. 对请求和响应对象进行更改。
    4. 结束请求-响应周期。
    5. 调用堆栈中的下一个中间件函数。
    6. 如果当前的中间件函数没有结束请求-响应周期, 它必须调用 next() 将控制传递给下一个中间 件函数。否则, 请求将被挂起。

    二、NestJS 中创建使用中间件

  • https://docs.nestjs.cn/8/middlewares

    1、创建中间件

    ```typescript nest g middleware middleware/init

// 创建完成生成下面的代码 import { Injectable, NestMiddleware } from ‘@nestjs/common’; @Injectable() export class InitMiddleware implements NestMiddleware { use(req: any, res: any, next: () => void) { console.log(‘init中间件’) next(); } }

  1. <a name="Rc61H"></a>
  2. ##### 2、配置中间件,中间件不能在 @Module() 装饰器中列出。我们必须使用模块类的 configure() 方法来设置它们。包含中间件的模块必须实现 NestModule 接口。我们将 LoggerMiddleware 设置在 ApplicationModule 层上
  3. ```typescript
  4. // 在 src/app.module.ts 中继承 NestModule 然后配置中间件
  5. import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
  6. import { InitMiddleware } from './middleware/init.middleware'; // 引入中间件
  7. export class AppModule implements NestModule {
  8. configure(consumer: MiddlewareConsumer) {
  9. consumer.apply(InitMiddleware)
  10. // .forRoutes('*'); // 表示匹配所有的路由
  11. // .forRoutes('user'); // 表示只有访问user路由的时候才走这个中间件
  12. // .forRoutes({ path: 'user', method: RequestMethod.All }); // 路由中的所有方法匹配中间件
  13. // .forRoutes({ path: 'user', method: RequestMethod.GET }); // 路由中的GET方法匹配中间件
  14. .forRoutes( // user和news路由匹配中间件
  15. { path: 'user', method: RequestMethod.GET },
  16. { path: 'news', method: RequestMethod.All },
  17. );
  18. }
  19. }

三、多个中间件

  1. // 下面表示所有路由都匹配 InitMiddleware 中间件,user不仅匹配 InitMiddleware 中间件,还匹配 UserMiddleware 中间件
  2. consumer.apply(InitMiddleware).forRoutes('*').apply(UserMiddleware).forRoutes('user')
  3. // 下面表示 user 和 news 路由都匹配 NewsMiddleware 和 NewsMiddleware 中间件
  4. consumer.apply(UserMiddleware, NewsMiddleware).forRoutes(
  5. { path: 'user', method: RequestMethod.GET },
  6. { path: 'news', method: RequestMethod.GET },
  7. )

四、函数式中间件 - NestJS不常用

  1. function logger(req, res, next) {
  2. console.log('函数式中间件');
  3. next();
  4. };
  5. // 使用函数式中间件和正常使用一样
  6. consumer.apply(logger).forRoutes('*');

五、全局中间件

  1. // src/main.ts 全局中间件只能引入函数式中间件
  2. import { logger } from './middleware/logger.middleware'; // 引入中间件
  3. app.use(logger)