Middleware는 route 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();
}
}
Nest Middleware는 종속성 주입을 지원한다. Provider 및 Controller와 마찬가지로, 동일한 Module 안에서 사용 가능한 종속성을 주입할 수 있다. (평소와 같이 constructor
를 통해 수정한다.)
@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
에서 json
및 urlencoded
를 등록한다.
즉, MiddlewareConsumer를 통해 해당 미들웨어를 사용자 정의하려면 NestFactory.create()
로 애플리케이션을 생성할 때 bodyParser 플래그를 false로 설정하여 전역 미들웨러를 꺼야된다.
패턴 기반 route도 지원이 된다. 예를 들어, 별표는 와일드카드로 사용되고, 모든 문자 조합과 일치한다.
forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
'ab*cd'
route 경로는 abcd
, ab_cd
, abecd
, 등과 일치하다. 문자 ?
, +
, *
, ()
는 route 경로에서 사용할 수 있으며 해당 정규식의 하위 집합이다. 하이픈(-)과 점(.)은 문자 그대로 문자열 기반 경로로 해석된다.
감사합니다. 이런 정보를 나눠주셔서 좋아요.