nestjs
NestJS의 동적 모듈(Dynamic Modules)을 다루다 보면, forRoot, register, forFeature와 같은 메서드를 자주 보게 됩니다. 이들 메서드는 각각 모듈의 설정과 사용 방식에 대해 약간의 차이를 두고 있는데, NestJS 커뮤니티에서는 다음과 같은 가이드라인을 따르는 것을 권장합니다.
먼저, register 메서드는 동적 모듈을 생성할 때 호출하는 모듈별 설정을 위해 사용됩니다. 이 방식을 채택하면, 호출하는 각 모듈이 개별적인 구성을 할 수 있습니다. 예를 들어, Nest의 @nestjs/axios 패키지에서는
반면, forRoot 메서드는 동적 모듈을 한 번만 설정하고, 그 구성을 애플리케이션 전체에서 재사용할 때 사용됩니다. 예를 들어, GraphQL이나 TypeORM과 같은 패키지에서는 각각 하나의 forRoot 호출로 전체 애플리케이션에서 동일한 데이터베이스 연결 설정이나 GraphQL 스키마를 사용합니다. 이 방식은 모듈의 설정이 애플리케이션 전역에서 공유되기 때문에, 한 번 설정된 구성이 모든 곳에 적용되며, 코드의 일관성을 유지할 수 있습니다.
또한, forFeature 메서드는 이미 forRoot를 통해 설정된 글로벌 구성을 기반으로, 특정 모듈의 필요에 따라 추가적인 설정을 적용할 때 사용됩니다. 예를 들어, 데이터베이스 모듈에서는 특정 모듈이 접근해야 할 리포지토리를 지정하거나, 로거의 컨텍스트를 조정하는 등의 작업을 할 수 있습니다. 즉, 전역 구성을 바탕으로 해당 모듈만의 특수한 요구 사항을 덧붙이고자 할 때 매우 유용합니다.
NestJS의 동적 모듈을 구성할 때, 동기 방식(register, forRoot, forFeature) 외에도 비동기적으로 모듈을 구성할 필요가 있는 경우가 있습니다. 예를 들어, 환경 변수, 원격 설정 서비스, 데이터베이스 연결 등 비동기 작업을 통해 설정 값을 불러와야 하는 상황에서는 동기 방식으로는 해결할 수 없는 문제가 발생합니다. 이럴 때 NestJS는 registerAsync, forRootAsync, forFeatureAsync와 같은 비동기(Async) 메서드를 제공합니다.
비동기 메서드들은 기본적으로 팩토리 패턴(Factory Pattern)을 활용합니다. 구체적으로, 이 메서드들에 전달하는 옵션 객체는 보통 다음과 같은 속성들을 포함합니다.
이런 비동기 옵션을 사용하면, NestJS는 애플리케이션이 부팅될 때 해당 팩토리 함수가 모든 필요한 비동기 작업(예: 원격 API 호출, 데이터베이스에서 설정 값 조회 등)을 완료한 후 설정 객체를 받아 모듈을 구성합니다. 결과적으로, 동적 모듈이 애플리케이션 전역이나 특정 기능 모듈에 도입되기 전에 모든 비동기 종속성이 해결되고, 올바른 설정 값으로 초기화됩니다. 예를 들어, 데이터베이스 연결 설정을 외부 구성 파일이나 환경 변수에서 비동기적으로 읽어와야 한다면, forRootAsync를 사용할 수 있습니다. 다음은 간단한 예시입니다.
@Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
type: 'postgres',
host: configService.get('DB_HOST'),
port: +configService.get<number>('DB_PORT'),
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
위 예제에서는 TypeOrmModule의 forRootAsync 메서드를 사용해 데이터베이스 연결 설정을 비동기적으로 가져옵니다. ConfigModule을 임포트하고, ConfigService를 주입받아 팩토리 함수 내에서 필요한 환경 변수 값을 읽어온 후, 데이터베이스 설정 객체를 반환합니다. 이렇게 하면 애플리케이션이 시작되기 전에 모든 비동기 작업이 완료되어 올바른 설정 값으로 모듈이 구성됩니다.