[NestJS] Middleware

곽태민·2023년 7월 24일
0

NestJS

목록 보기
6/8

Middleware

Middlewareroute handler보다 먼저 호출되는 함수다. 미들웨어의 기능은 애플리케이션의 요청-응답 주기에서 요청 및 응답 객체와 next() 미들웨어 기능에 액세스할 수 있다.

NestJS의 Middleware는 기본적으로 Express Middleware와 동일하다. 다음은 공식 Express 문서에서 Middleware의 기능을 설명한다.

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

NestJS에서 Middleware를 구현할 때, 함수나 @Injectable() 데코레이터가 있는 클래스에서 Custom Nest Middleware를 구현한다.

클래스는 NestMiddleware 인터페이스를 구현해야하지만 함수에는 특별 요구 사항이 없다. 클래스 메서드를 사용해서 간단한 Middlewre 기능을 구현하는 예시는 아래와 같다.

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();
    }
}

Dependency Injection

Nest Middleware는 종속성 주입을 지원한다. Provider 및 Controller와 마찬가지로, 동일한 Module 안에서 사용 가능한 종속성을 주입할 수 있다. (평소와 같이 constructor를 통해 수정한다.)

Applying Middlware

@Module() 데코레이터에는 Middleware를 위한 자리가 없다. 대신에 Module 클래스의 configure() 메서드를 사용하여 설정한다.

Middlware를 포함하는 Module은 NestModule 인터페이스를 구현해야 한다. AppModule 수준에서 LoggerMiddlware를 설정해 보겠다.

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');
  }
}

위 예제에서는 이전에 CatsController 내부에 정의된 /cats 경로 처리 관련하여 LoggerMiddleware를 설정했다.

또한 Middleware를 구성할 때 route 경로 및 요청 메서드를 포함하는 객체를 forRoutes() 메서드에 전달하여 Middleware를 특정 요청 메서드로 제한할 수 있다.

아래 예제는 원하는 요청 메서드 유형을 참조하기 위해서 RequestMethod enum을 가져온다.

import { Module, NestModule, RequestMethod, 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({ path: 'cats', method: RequestMethod.GET });
  }
}

configure() 메서드는 async/await을 사용하여 비동기화할 수 있다. 그리고 Express 어댑터를 사용하는 경우 NestJS 앱은 기본적으로 body-parser에서 jsonurlencoded를 등록한다.

즉, MiddlewareConsumer를 통해 해당 미들웨어를 사용자 정의하려면 NestFactory.create()로 애플리케이션을 생성할 때 bodyParser 플래그를 false로 설정하여 전역 미들웨러를 꺼야된다.

Route wildcards

패턴 기반 route도 지원이 된다. 예를 들어, 별표는 와일드카드로 사용되고, 모든 문자 조합과 일치한다.

forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });

'ab*cd' route 경로는 abcd, ab_cd, abecd, 등과 일치하다. 문자 ?, +, *, ()는 route 경로에서 사용할 수 있으며 해당 정규식의 하위 집합이다. 하이픈(-)과 점(.)은 문자 그대로 문자열 기반 경로로 해석된다.

profile
Node.js 백엔드 개발자입니다!

1개의 댓글

comment-user-thumbnail
2023년 7월 24일

감사합니다. 이런 정보를 나눠주셔서 좋아요.

답글 달기