미들웨어는 Route Handler
보다 먼저 호출되는 함수입니다.
Controller에 넘어가는 HttpRequest를 사전에 캐치하여 특정 작업을 수행할 수 있습니다.
보안을 위해 권한 검사
를 해당 단계에서 실행할 수 있습니다.
next()
함수를 통해 다음 단계로 제어를 전달합니다.
특정 Request에 ‘Http Request is coming...’
라는 console를 출력하는 Middleware를 생성해보겠습니다.
$ nest g middleware [middleware-name]
해당 cli를 통해 middleware 객체를 생성하면 다음과 같은 파일이 생성됩니다.
import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
next();
}
}
현재 request, response가 모두 any
로 되어있으므로 다음과 같이 Type
을 설정해줍니다.
그리고 next() 함수 이전에 실행할 console.log(…)
입력합니다.
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('Http Request is coming...');
next();
}
}
Module
단에서 미들웨어를 적용할 수 있습니다.
@Module
데코레이터에는 미들웨어를 위한 인자가 없으므로 configure
메서드를 사용해서 설정합니다.
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’
route 경로에 middleware
를 적용할 수 있습니다.
만약 아래와 같이 forRoute를 설정하면 특정 method에만 middleware
를 적용할 수 있습니다.
forRoutes({ path: 'cats', method: RequestMethod.GET });
또한, 아래와 같이 패턴 기반 경로도 가능합니다.
forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
Middleware Consumer
를 사용하면 좀 더 간편하게 여러 middleware를 적용 및 설정이 가능합니다.
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(cors(), helmet(), LoggerMiddleware)
.exclude(
{ path: 'cats', method: RequestMethod.GET },
{ path: 'cats', method: RequestMethod.POST },
'cats/(.*)',
)
.forRoutes(CatsController);
}
}