미들웨어어는 라우트 핸들러보다 먼저 호출되는 함수입니다. 미들웨어 기능은 애플리케이션의 요청-응답 주기에서 요청 및 응답 객체와 미들웨어 기능에 액세스할 수 있습니다.
Nest 미들웨어는 기본적으로 express 미들웨어와 동일합니다.
미들웨어 기능은 다음 작업을 수행할 수 있습니다.
$ nest g middleware <middleware-name>
$ nest g middleware logger
logger.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(req.ip);
next();
}
}
@Injectable() 가 있다는 것은 의존성 주입이 가능하는 것을 뜻합니다.
함수 또는 @Injectable() 데코레이터가 있는 클래스에서 커스텀 Nest 미들웨어를 구현합니다. 클래스는 NestMiddleware 인터페이스를 구현해 하지만 함수에는 특별한 요구사항이 없습니다.
위의 코드는 요청이 들어오면 요청의 ip를 콘솔에 출력하는 역할을 합니다. 하지만 이 코드를 작성한다고 자동으로 추가되지 않습니다.
@Module() 데코레이터에는 미들웨어를 위한 자리가 없습니다. 대신 @Configure() 모듈 클래스의 메서드를 사용하여 설정합니다.
app.module.ts
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';
import { LoggerMiddleware } from './logger/logger.middleware';
@Module({
imports: [CatsModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('cats');
}
}
cats 라우터에 오는 요청들에 대해서 LoggerMiddleware를 사용하는 것을 확인할 수 있습니다. 모든 라우터에 오는 요청들에 대해 LoggerMiddleware을 추가하고 싶다면 아래와 같이 설정하면 됩니다.
consumer.apply(LoggerMiddleware).forRoutes('*');
console에 값이 잘 찍히는 것을 확인할 수 있습니다. 이제 Nest에서 제공하는 log 기능을 추가하여 로그를 찍어보도록 하겠습니다.
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
private logger = new Logger('http');
use(req: Request, res: Response, next: NextFunction) {
console.log('LoggerMiddleware');
this.logger.log(req.originalUrl);
this.logger.log(req.ip);
this.logger.log(req.method);
console.log('LoggerMiddleware');
next();
}
}
이제 모든 요청에 대해서 로그를 남길 수 있게 되었습니다. 다음은 응답에 대한 로그를 남겨보도록 하겠습니다.
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
private logger = new Logger('http');
use(req: Request, res: Response, next: NextFunction) {
console.log('LoggerMiddleware');
this.logger.log(req.originalUrl);
this.logger.log(req.ip);
this.logger.log(req.method);
res.on('finish', () => {
this.logger.log(res.statusCode);
});
console.log('LoggerMiddleware');
next();
}
}
위의 결과를 보듯이 console.log('LoggerMiddleware'); 코드가 마지막에 있지만 statusCode가 마지막에 로그로 남는 것을 확인할 수 있습니다.
해당 게시글은 "NestJS 공식 홈페이지"와
인프런 강의 "탄탄한 백엔드 NestJS, 기초부터 심화까지(윤상석)"을 참고하여 만들었습니다.