끄적이는 개발노트
NestJS - Middleware 본문
이번 포스트에서는 NestJS에서 middleware를 사용하는 방법을 알아본다.
Middleware
미들웨어는 라우터 핸들러 전에 호출되는 함수다. 미들웨어 기능은 요청(request) 및 응답(response) 객체 및 어플리케이션의 요청-응답주기에서 next() 미들웨어 함수이다. next 미들웨어 함수는 일반적으로 next 라는 변수로 표시된다.
NestJS 미들웨어는 기본적으로 express 미들웨어와 동일하다. 공식 express 문서를 통해 미들웨어의 기능을 알아본다.
미들웨어 기능은 다음 작업을 수행할 수 있다.
- 모든 코드를 실행
- 요청 및 응답 객체를 변경
- 요청-응답주기를 종료
- 스택의 next 미들웨어 함수를 호출
- 현재 미들웨어 함수가 요청-응답주기를 종료하지 않으면 next()를 호출하여 next 미들웨어 기능에 제어를 전달
(그렇지 않을 경우 요청 중단)
그러면 간단한 Middleware를 만들어 보자.
1. 미들웨어 폴더 생성 및 파일 생성
위와 같이 src 아래에 middleware 폴더와 그 안에 아래 코드를 담은 파일을 생성한다.
미들웨어가 정상작동한다면 'Request...' 라는 로그가 찍히는 미들웨어이다.
/src/middleware/logger.middleware.ts
// /src/middleware/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();
}
}
2. 미들웨어 추가
AppModule 레벨에서 LoggerMiddleware를 설정한다.
Route
// 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');
}
}
위의 코드에서 CatsController 내부에 정의된 /casts 라우트 핸들러에 대해 LoggerMiddleware를 설정했다.
Path + Method
// app.module.ts
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 });
}
}
또한, 위와 같이 미들웨어를 구성할 때 path 라우트가 포함된 객체를 전달하고 method를 forRoutes() 메서드에 요청하여 미들웨어를 특정 요청 메서드로 제한할 수 있다.
path에 패턴기반, 와일드카드도 사용 가능하다.
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);
}
}
위의 예시처럼 아예 컨트롤러를 연결지을 수도 있다.
실행화면
'Request...' 가 로그에 출력되는 것을 확인할 수 있다.
3. 특정 라우트 제외
// app.module.ts
...
consumer
.apply(LoggerMiddleware)
.exclude(
{ path: 'cats', method: RequestMethod.GET },
{ path: 'cats', method: RequestMethod.POST },
'cats/(.*)',
)
.forRoutes(CatsController);
위의 예에서 LoggerMiddleware는 exclude() 메소드에 전달된 세개를 제외하고 CatsController 내에 정의된 모든 라우트에 바인딩된다.
4. 미들웨어 여러개 추가
순차적으로 실행되는 여러 미들웨어를 바인딩하는 경우, apply() 메서드 내에 순서에 맞게 쉼표로 나열하면 된다.
// app.module.ts
...
consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
5. 글로벌 미들웨어
미들웨어를 등록된 모든 경로에 한번에 바인딩하려면 use() 메서드를 사용한다.
// main.ts
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
이상으로 NestJS에서 미들웨어를 사용하는 방법을 알아보았다.
'JavaScript > NestJS' 카테고리의 다른 글
NestJS - JWT 토큰 기반 인증 구현 (2) (0) | 2023.06.19 |
---|---|
NestJS - JWT 토큰 기반 인증 구현 (1) (0) | 2023.06.19 |
NestJS와 MongoDB 연결하기(3) - CRUD (0) | 2021.10.08 |
NestJS와 MongoDB 연결하기(2) - Module, Service, Controller (0) | 2021.10.08 |
NestJS와 MongoDB 연결하기(1) - 설치 및 스키마 정의 (0) | 2021.10.08 |