背景
使用 nestjs 开发几个月了,回头发现基础知识掌握的不是很牢固。于是用写文章的形式对基础知识做一个梳理。
中间件
nestjs 中的中间件在默认情况下等同于 express 中间件。
express 文档中对 中间件的功能描述如下:
- 执行任何代码
- 更改请求和响应对象
- 结束请求 - 响应循环
- 调用 next 函数,执行堆栈中的下一个中间件函数
- 如果当前中间件没有结束请求响应,则必须调用 next 函数执行堆栈下一个中间件函数,否则函数会被挂起。
实现
中间件分为两类:
- 类中间件
- 函数中间件
类中间件主要用于需要依赖注入的场景,函数中间件不需要依赖注入的场景。
类中间件的实现
类中间件完全支持依赖注入。通过 constructor 实现。
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();
}
}
函数中间件的实现
import { Request, Response, NextFunction } from 'express';
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
};
使用中间件
对于在模块中使用,我们需要实现模块类 NestModule ,在模块类中的configure() 方法设置它们。
forRoutes() 方法可以接受单个字符串、多个字符串、一个 RouteInfo 对象、一个控制器类甚至多个控制器类。
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('cats');
}
}
全局中间件
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
业务场景
目前的开发场景中用到中间件的场景其实很少,大多使用守卫和过滤器等功能。目前使用全局中间件实现了对请求加traceid 的功能。