Published on

Nestjs Middleware | Nestjs Docs

Authors
  • avatar
    Name
    JaeHyeok CHOI
    Twitter
    none

Nestjs Middleware

Nestjs Middleware

Middleware는 HTTP 요청을 처리하기 전에 실행되는 함수입니다.

미들웨어 함수들은 request와 response 객체와 next() 미들웨어 함수에 접근할 수 있습니다.

Next 미들웨어는 기본적으로 express 미들웨어와 동일하며 Express 공석 문서의 기능은 다음과 같습니다.

  • 모든 코드를 실행합니다.
  • 요청 및 응답 객체를 변경합니다.
  • 요청-응답 주기를 종료합니다.
  • 스택의 다음 미들웨어 함수를 호출합니다.
  • 현재 미들웨어 함수가 요청-응답 주기를 종료하지 않으면 next()다음 미들웨어 함수로 제어권을 넘기기 위해 호출해야 합니다. 그렇지 않으면 요청은 중단 상태로 남게 됩니다.

사용자 지정 Nest 미들웨어는 함수 @injectable() 데코러에터가 있는 클래스에서 구현할 수 있습니다.

클래스는 NestMiddleware 인터페이스를 구현해야 하지만, 함수는 특별한 요구사항이 없습니다. 클래스 메서드를 사용하여 간단한 미들웨어 기능을 구현하는 것 부터 보겠습니다.

Fastify의 다른 메서드 시그니처는 구현 방안이 다르니 여기를 참고해주세요.

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

의존성 주입

Nest 미들웨어는 의존성 주입을 완벽하게 지원합니다. Provider와 Controller와 마찬가지로, 동일한 모듈 내에서 사용 가능한 의존성을 주입할 수 있습니다.

미들웨어 적용

데코레이터에는 미들웨어를 위한 공간이 없습니다. 대신 모듈 클래스의 메서드를 @Module()을 사용해 미들웨어를 설정합니다.

미들웨어를 포함하는 모듈은 NestModule 인터페이스를 구현해야 합니다.

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

위 예시에서 /cats 경로 핸들러에 대한 LoggerMidleCatsController에 적용했었습니다.

미들웨어를 구성할 때, 경로 path와 request method를 forRoutes() 에 전달해줌으로써 특정 요청 method에 대한 미들웨어를 제한할 수 있습니다.

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

express 어댑터를 사용하면 NestJS 앱은 기본적으로 body-parser 패키지로부터 json 과 urlencoded 를 등록합니다. 이는 MiddlewareConsumer를 사용하여 미들웨어를 커스텀하고 싶을 경우, NestFactory.create()와 앱을 생성할 때 bodyParser 플래그를 false로 설정하여 전역 미들웨어를 꺼주어야 합니다.

Route wildcards

Middleware Consumer

MiddlewareConsumer는 helper 클래스입니다. 이는 서버 빌트인 함수로써, 미들웨어를 관리하는 기능을 제공합니다.

이 메서드들은 모두 fluent style로 연속적으로 엮을 수 있습니다. forRoutes() 메서드는 string, multiple string, RouteInfo object, 컨트롤러 클래스, 여러 컨트롤러 클래스를 받을 수 있습니다.

대부분의 경우 쉼표로 구분된 컨트롤러 목록을 전달하게 됩니다.


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

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

| apply() | 미들웨어를 적용합니다. | | forRoutes() | 미들웨어를 적용할 route를 지정합니다. | | exclude() | 미들웨어를 적용하지 않을 route를 지정합니다. | | all() | 모든 route에 미들웨어를 적용합니다. | | use() | 미들웨어를 적용합니다. |

함수형 미들웨어

우리가 사용해온 LoggerMiddleware는 매우 간단합니다. 멤버, 추가 메서드, 종속성도 없습니다. 이를 함수형으로 선언할 수도 있습니다.

함수형 미들웨어는 매우 간단합니다.

//logger.middleware.ts

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

export function logger(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(CatsController);
  }
}

다중 미들웨어

  • 공식 문서 참조

글로벌 미들웨어

  • 공식 문서 참조