[NestJS] Nest 미들웨어

이재훈·2023년 5월 28일
0

NestJs

목록 보기
5/8

미들웨어

미들웨어어는 라우트 핸들러보다 먼저 호출되는 함수입니다. 미들웨어 기능은 애플리케이션의 요청-응답 주기에서 요청 및 응답 객체와 미들웨어 기능에 액세스할 수 있습니다.

Nest 미들웨어는 기본적으로 express 미들웨어와 동일합니다.

미들웨어 기능은 다음 작업을 수행할 수 있습니다.

  • 모든 코드를 실행합니다.
  • 요청 및 응답 객체를 변경합니다.
  • 요청-응답 주기를 종료합니다.
  • 스택에서 미들웨어 함수를 호출합니다.
  • 현재 미들웨어 기능이 요청-응답 주기를 종료하지 않으면 next() 다음 미들웨어 기능으로 제어를 전달하도록 호출해야 합니다. 그렇지 않으면 요청이 중단됩니다.

미들웨어 만들기

$ 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, 기초부터 심화까지(윤상석)"을 참고하여 만들었습니다.

profile
부족함을 인정하고 노력하자

0개의 댓글