반응형

다음은 이 글의 동영상 강의입니다.

https://youtu.be/MEaTJTyHVnc

다음은 실습 동영상입니다.

https://youtu.be/J8HWEoZSC-Y

 

* 이 글은 nestjs 공식 홈페이지를 참조하여 작성하였습니다.

https://docs.nestjs.kr/middleware

 

네스트JS 한국어 매뉴얼 사이트

네스트JS 한국, 네스트JS Korea 한국어 매뉴얼

docs.nestjs.kr

Nest의 미들웨어란?

미들웨어는 라우터 핸들러 이전에 호출되는 함수입니다.

Middlewar

다시말해 위 그림에서와 같이 클라이언트의 요청을 라우터 핸들러가 받기 전에 가로채 다른 작업을 처리할 수 있습니다.

이를 응용하면 여러가지 공통적으로 처리해야 하는 부분들의 처리를 중복 없이 개발할 수 있습니다.

예를 들면 다음과 같은 것들을 할 수 있습니다.

  • 모든 코드가 공통으로 실행해야 하는 인증, 로깅등을 처리할 수 있습니다.
  • 요청과 응답 객체를 변경할 수 있습니다.
  • 요청의 validation을 체크하여 오류 처리를 할 수 있습니다.

 

Nest의 미들웨어 사용법

Nest에서 미들웨는 다음과 같이 사용할 수 있습니다.

  • @Injectable 데코레이터를 사용합니다.
  • NestMiddleware 인터페이스를 implements 해서 사용합니다.
  • Module의 class 내부에 configure를 사용하여 선언합니다. 이때 NestModule 인터페이스를 implements 합니다.

다음은 Log를 위한 Middleware 예제입니다.

지금까지의 실습 소스는 아래 git 주소에서 받으시면 됩니다.

https://github.com/CodeGearGit/nest-cats.git

 

GitHub - CodeGearGit/nest-cats

Contribute to CodeGearGit/nest-cats development by creating an account on GitHub.

github.com

logger.middleware.ts

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

app.module.ts

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

다음과 같이 라우트를 특정하여 사용할 수도 있습니다.

.forRoutes({ path: 'cats', method: RequestMethod.GET });

다음과 같이 패턴 기반의 라우팅도 지원됩니다.

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

 

Middleware 관리를 위한 내장 모듈 - MiddlewareConsumer

MiddlewareConsumer라는 헬퍼클래스를 사용하면 여러 스타일로 미들웨어를 설정할 수 있습니다.

forRoutes() 메소드는 단일 문자열, 여러 문자열, RouteInfo 객체, 컨트롤러 클래스 및 여러 컨트롤러 클래스를 사용할 수 있습니다.

다음은 Controller의 사용 예입니다.

app.module.ts

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller.ts';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}

apply 메서드는 여러 미들웨어를 지정할 수 있습니다.

 

라우트 예외처리

다음과 같이 exclude() 메소드로 라우트를 제외할 수 있습니다.

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/(.*)',
  )
  .forRoutes(CatsController);

Functional middleware

지금까지 만든 Class 미들웨어는 아래와 같이 간단한 Funtional middleware로 변경할 수 있습니다.

logger.middleware.ts

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};

위의 logger functrion은 Module에서 다음과 같이 사용할 수 있습니다.

app.module.ts

consumer
  .apply(logger)
  .forRoutes(CatsController);

 

여러개 미들웨어 사용

다음과 같이 apply() 메서드에 여러개의 미들웨어를 사용할 수 있습니다,

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);

Global 미들웨어

모든 경로에서 사용하는 미들웨어는 INestApplication 인스턴스에서 제공하는 user() 메서드를 사용할 수 있습니다.

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
  • 단, Global 미들웨어에서 DI 컨테이너에 액세스할 수 없습니다.
  • app.use()에서 미들웨어를 사용할 때는 대신 functional middleware를 사용하고 있습니다.

반응형

+ Recent posts