Nestjs 知识梳理 - 中间件

80 阅读2分钟

背景

使用 nestjs 开发几个月了,回头发现基础知识掌握的不是很牢固。于是用写文章的形式对基础知识做一个梳理。

中间件

nestjs 中的中间件在默认情况下等同于 express 中间件。

express 文档中对 中间件的功能描述如下:

  • 执行任何代码
  • 更改请求和响应对象
  • 结束请求 - 响应循环
  • 调用 next 函数,执行堆栈中的下一个中间件函数
  • 如果当前中间件没有结束请求响应,则必须调用 next 函数执行堆栈下一个中间件函数,否则函数会被挂起。

实现

中间件分为两类:

  • 类中间件
  • 函数中间件

类中间件主要用于需要依赖注入的场景,函数中间件不需要依赖注入的场景。

类中间件的实现

类中间件完全支持依赖注入。通过 constructor 实现。

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}

函数中间件的实现

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};

使用中间件

对于在模块中使用,我们需要实现模块类 NestModule ,在模块类中的configure() 方法设置它们。

forRoutes() 方法可以接受单个字符串、多个字符串、一个 RouteInfo 对象、一个控制器类甚至多个控制器类。

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}

全局中间件

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);

业务场景

目前的开发场景中用到中间件的场景其实很少,大多使用守卫和过滤器等功能。目前使用全局中间件实现了对请求加traceid 的功能。