Global로 등록하는 filter안에 dependency injection 하는 방법에 대해 알아보자.
이 글은 NestJS 공식문서 와 StackoverFlow의 관련된 글을 참고했습니다.
Problem - 기존 방법
기존에 사용했던 방법은 아래처럼 main.ts에 useGlobalFilter() 메소드를 사용하여 filter를 등록하는 방법이었다.
//main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();
하지만, 이렇게 등록하게 되면 해당 필터는 NestJS의 어떠한 모듈에도 등록되지 않고, 모듈 밖에 등록 되게 된다.
그러므로, dependency injection 또한 불가능 해지는 문제점이 생긴다.
1. Error Message
만약, 위의 방식으로 filter를 등록한 채로 dependency injection 을 하게 된다면 아래와 같은 에러 메시지를 받게 될 것이다.
src/main.ts:19:24 - error TS2554: Expected 1 arguments, but got 0.
19 app.useGlobalFilters(new HttpExceptionFilter());
~~~~~~~~~~~~~~~~~~~~~~~~~
src/common/http-exception.filter.ts:23:15
23 constructor(private systemLogService: SystemLogService) {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An argument for 'systemLogService' was not provided.
참고로, 의존성 주입을 하려고 하는 HttpExceptionFilter의 코드는 아래와 같다.
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
constructor(private systemLogService: SystemLogService) {}
//...
}
2. Reason
코드를 보면 위의 에러는 너무 당연하다. class HttpExceptionFilter는 어떠한 모듈에도 등록이 되어 있지 않은 상황에서
main.ts에서 인스턴스를 생성하려고 한다.
하지만, 우리는 의존성 주입을 위해, systemLogService라는 provider를 생성자 함수의 인자로 넣어줘야 함에도 main.ts에서는 해당 인자를 넘겨주고 있지 않기 때문이다.
Solution
위의 문제는 아래 방식 처럼, global filter를 module안에 등록해주는 방식으로 매우 간단히 해결할 수 있다.
import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_FILTER,
useClass: HttpExceptionFilter,
},
],
})
export class AppModule {}
'NestJS' 카테고리의 다른 글
main.ts 에서 nestjs module 사용하기 (feat. nestjs 서버 시작 로그 남기기) (0) | 2022.05.12 |
---|---|
nestjs Logger Middleware 만들기(feat. log db저장) (0) | 2022.05.12 |
nestJS app 밖에서 nestJS application instance 사용하기 (0) | 2022.04.29 |
migration 으로 DB 초기값 설정(with typeorm) (0) | 2022.04.28 |
NestJS의 기초 (0) | 2022.04.11 |