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 所有路由生效
}
}全局中间件
- 方式一:通过 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 {}- 方式二:通过 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 支持三种路由匹配方式,满足精细化控制
- 匹配路由规则 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 }
);- 排除路由规则 exclude
ts
consumer
.apply(LogMiddleware)
.exclude(
{ path: 'health', method: RequestMethod.GET }, // 排除 GET /health
'public/*' // 排除 /public 下所有路由
)
.forRoutes('*'); // 对所有路由生效(除排除项)