【Nest】中间件
2021/09/06 18:13:59
中间件是在路由处理程序之前调用的函数,路由处理程序相当于当前请求-响应周期的最后一个中间件。
如果当前的中间件函数没有结束请求-响应周期,它必须调用 next() 将控制传递给下一个中间件函数。否则,请求将被挂起。
Nest 中间件实际上等价于 Express 中间件。
包含中间件的模块必须实现 NestModule 接口。
定义中间件
- 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 上注册,可以配置应用该中间件的路由、请求方式。
- app.module.ts
import {
Module,
NestModule,
MiddlewareConsumer,
RequestMethod,
} from "@nestjs/common";
import { AppController } from "./app.controller";
import { LoggerMiddleware } from "./middleware/login.middleware";
@Module({
controllers: [AppController],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes({
path: "cats",
method: RequestMethod.GET,
});
}
}
排除路由
使用 exclude() 来排除指定路由。
- app.module.ts
import {
Module,
NestModule,
MiddlewareConsumer,
RequestMethod,
} from "@nestjs/common";
import { AppController } from "./app.controller";
import { LoggerMiddleware } from "./middleware/login.middleware";
@Module({
controllers: [AppController],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.exclude(
{ path: "cats", method: RequestMethod.GET },
{ path: "cats", method: RequestMethod.POST },
"cats/(.*)"
)
.forRoutes(CatsController);
}
}
函数式中间件
对于没有成员,没有额外的方法,没有依赖关系的简单中间件,可以直接使用一个简单函数。
- logger.middleware.ts
export function logger(req, res, next) {
console.log(`Request...`);
next();
}
- app.module.ts
import {
Module,
NestModule,
MiddlewareConsumer,
RequestMethod,
} from "@nestjs/common";
import { AppController } from "./app.controller";
import { logger } from "./middleware/login.middleware";
@Module({
imports: [],
controllers: [AppController],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(logger).forRoutes({
path: "cats",
method: RequestMethod.GET,
});
}
}
全局中间件
如果我们想一次性将中间件绑定到每个注册路由,我们可以使用由 INestApplication 实例提供的 use()方法:
- main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);