Skip to content

NestJS 中间件绑定方式

NestJS中间件支持局部注册(模块级)、全局注册(全接口生效)

局部绑定

通过模块的 configure 方法(需实现 NestModule 接口),使用 MiddlewareConsumer 精细化控制中间件的生效路由、排除路由。

ts
// src/app.module.ts
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { AppController } from './app.controller';
import { LogMiddleware } from './middlewares/log.middleware';
import { TimeoutMiddleware } from './middlewares/timeout.middleware';

@Module({
  controllers: [AppController],
  providers: [LogMiddleware], // 类中间件需注册为 provider
})
export class AppModule implements NestModule {
  // 配置中间件
  configure(consumer: MiddlewareConsumer) {
    consumer
      // 应用中间件(可传多个,按顺序执行)
      .apply(LogMiddleware, TimeoutMiddleware)
      // 指定生效路由(支持多种匹配方式)
      .forRoutes(AppController); // 对 AppController 所有路由生效
  }
}

全局中间件

  1. 方式一:通过 providers 注册(推荐,支持依赖注入)
ts
// src/app.module.ts
import { Module, Provider } from '@nestjs/common';
import { APP_MIDDLEWARE } from '@nestjs/core';
import { LogMiddleware } from './middlewares/log.middleware';

// 注册为全局中间件(支持 DI)
const globalMiddlewareProvider: Provider = {
  provide: APP_MIDDLEWARE,
  useClass: LogMiddleware,
  multi: true, // 允许多个全局中间件
};

@Module({
  providers: [LogMiddleware, globalMiddlewareProvider],
})
export class AppModule {}
  1. 方式二:通过 NestFactory 注册(不支持依赖注入)
ts
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { TimeoutMiddleware } from './middlewares/timeout.middleware';
import * as cors from 'cors';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 全局注册函数式中间件
  app.use(TimeoutMiddleware);
  // 全局注册原生 Express 中间件
  app.use(cors({ origin: ['https://example.com'] }));

  await app.listen(3000);
}
bootstrap();

作用范围(匹配规则)

forRoutes 支持三种路由匹配方式,满足精细化控制

  1. 匹配路由规则 forRoutes
shell
# 语法
类型             示例                                                  说明
字符串        .forRoutes('user')                                     匹配 /user 所有方法
正则表达式    .forRoutes(/^\/api\/.*$/)                             匹配 /api/* 所有路由
RouteInfo 对象  .forRoutes({ path: 'user', method: RequestMethod.GET }) 仅匹配 GET /user

# 示例:仅匹配 GET /user 和 POST /order 路由
import { RequestMethod } from '@nestjs/common';
consumer
  .apply(LogMiddleware)
  .forRoutes(
    { path: 'user', method: RequestMethod.GET },
    { path: 'order', method: RequestMethod.POST }
  );
  1. 排除路由规则 exclude
ts
consumer
  .apply(LogMiddleware)
  .exclude(
    { path: 'health', method: RequestMethod.GET }, // 排除 GET /health
    'public/*' // 排除 /public 下所有路由
  )
  .forRoutes('*'); // 对所有路由生效(除排除项)