Middleware 란?
NestJS docs - middleware
- 라우트 핸들러 이전에 호출되는 함수
- 요청/응답 객체에 접근 가능
next()
미들웨어 함수로 사용
기능
- 코드 실행
- 요청/응답 객체 변경
- 요청-응답 주기 종료
- 스택의 다음 미들웨어 함수 호출
- 현재 미들웨어 함수가 요청-응답 주기를 종료하지 않을 시,
next()
를 호출하여 다음 미들웨어 기능에 제어 전달
구현
- 함수 or
@Injectable()
데코레이터가 있는 클래스에서 커스텀 Nest 미들웨어 구현 가능
- 클래스의 경우, NestMiddleware
인터페이스를 구현해야 함
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...');
next();
}
}
적용
- 종속성 주입 지원(
constructor
이용)
@Module()
데코레이터 내에 미들웨어를 위한 위치 X
-> 모듈 클래스의 configure()
메소드 사용
- 미들웨어를 포함하는 모듈은
NestModule
인터페이스 구현해야 함
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes({ path: 'cats', method: RequestMethod.GET });
}
}
Route wildcards
- 패턴 기반 라우트 제공
?
, +
, *
, ()
, ...
ex. forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
- ab*cd
라우트 경로는 abcd
, ab_cd
, abecd
등과 일치
Middleware consumer
- 헬퍼 클래스
- 미들웨어 관리를 위한 빌트인 메서드 제공
forRoutes()
메소드
- 단일 문자열, 여러 문자열, RouteInfo
객체, 컨트롤러 클래스 등
- 대부분 컨트롤러 목록 전달 .forRoutes(CatsController, DogsController, ...);
Excluding routes
- 미들웨어 적용 시, 특정 라우트 제외하기
exclude()
메서드 사용
consumer
.apply(LoggerMiddleware)
.exclude(
{ path: 'cats', method: RequestMethod.GET },
{ path: 'cats', method: RequestMethod.POST },
'cats/(.*)',
)
.forRoutes(CatsController);
Functional middleware: 기능적 미들웨어
- 클래스 대신 함수 기반의 미들웨어 정의
- 멤버 / 추가 메서드 / 종속성이 없을 때, 간단하게 기능적 미들웨어 사용하는 것을 추천
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
};
consumer
.apply(logger)
.forRoutes(CatsController);