express의 미들웨어와 동등함
NestMiddleware interface를 implements한 다음 미들웨어를 작성하면 됨
next()는 필수
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
// class가 아니더라도 funcitonal middleware로도 사용 가능
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
private logger = new Logger('HTTP');
use(req: Request, res: Response, next: NextFunction): void {
const { ip, method, originalUrl } = req;
const userAgent = req.get('user-agent') || '';
res.on('finish', () => {
const { statusCode } = res;
const contentLength = res.get('content-length');
// console.log가 아니라 Logger.log or this.logger.log 사용함
// 후자는 new Logger(context)에서 context를 넣어준 경우 사용
// -> 이 로그가 어떤거랑 연관돼서 발생한 것인지 모르기 때문에 context로 구분하는거임
this.logger.log(
`${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
);
});
next();
}
}
app.module을 NestModule을 implements하고 사용
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { LoggerMiddleware } from './middlewares/logger.middleware';
import { AuthMiddleware } from './middlewares/auth.middleware';
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
// middleware는 consumer에 연결
consumer.apply(LoggerMiddleware, AuthMiddleware).forRoutes('*');
}
}
app.module말고 main에서 app.use를 사용
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// global middleware
app.use(JwtMiddleWare);
await app.listen(PORT);
}
특정 경로에서 미들웨어를 적용시키고 싶지 않은 경우
consumer
.apply(LoggerMiddleware, AuthMiddleware)
.exclude(
{ path: 'cats', method: RequestMethod.POST }
)
.forRoutes('*');