Skip to content

中间件是一个在路由处理程序之前调用的函数。

中间件函数可以访问请求响应对象,以及应用程序请求-响应周期中的 next() 中间件函数。 下一个中间件函数通常用名为 next 的变量表示。

TIP

可以在函数中或带有 @Injectable() 装饰器的中实现自定义 Nest 中间件。

类应该实现 NestMiddleware 接口,而函数则没有任何特殊要求

1.类方法实现

ts
// logger.middleware.ts
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();
  }
}

然后,我们在 module 中使用 configure() 方法来注册中间件:

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

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET })
      // .forRoutes(CatsController) //也可以匹配Controller
  }
}

如果要排除某些路由,可以使用 exclude() 方法:

ts
consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/{*splat}',
  )
  .forRoutes(CatsController);

TIP

exclude() 方法接受单个字符串多个字符串RouteInfo 对象来标识要排除的路由。

2.函数实现

函数中间件的实现,比类中间件的实现要简单很多:

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

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

然后在 app.module.ts 中引入:

ts
consumer
  .apply(logger)
  .forRoutes(CatsController);