中间件是一个在路由处理程序之前调用的函数。
中间件函数可以访问请求和响应对象,以及应用程序请求-响应周期中的 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);