Nest 앱모듈에서 @Module 데코레이터의 imports 부분에 SequelizeModule을 등록하는 부분에서 옵션을 별도의 파일로 관리하고 싶었다. 앱모듈에 모듈을 많이 등록할수록 앱모듈 코드가 계속 복잡해졌던 경험이 있기 때문이다.
그래서 SequlizeModuleOptions
타입의 옵션을 별도의 파일에 작성하고 export해주었다.
// ./src/config/sequelize.config.ts
import { SequelizeModuleOptions } from '@nestjs/sequelize';
export const sequelizeConfig: SequelizeModuleOptions = {
dialect: process.env.DATABASE_DIALECT as 'postgres',
host: process.env.DATABASE_HOST,
port: Number(process.env.DATABASE_PORT),
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_DATABASE,
models: [__dirname + '/../**/*.model.*'],
autoLoadModels: Boolean(process.env.DATABASE_AUTOLOADMODELS),
synchronize: Boolean(process.env.DATABASE_SYNCHRONIZE),
};
앱모듈은 다음과 같이 작성하였다.
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { ConfigModule } from '@nestjs/config';
import { sequelizeConfig } from './config/sequelize.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: `${__dirname}/config/env/.${process.env.NODE_ENV}.env`,
}),
SequelizeModule.forRoot(sequelizeConfig),
],
controllers: [],
providers: [],
})
export class AppModule {}
하지만 이 방식으로는 환경변수 값들을 제대로 읽어올 수 없었다.
import 구문에서 sequelize.config
파일을 읽는 과정에서 아직 환경변수 값들이 설정되지 않는 것을 확인했다. process.env.DATABASE_DIALECT
를 콘솔에 찍어보니 계속 undefined
가 출력되었다.
문제를 해결하기 위해 구글링한 결과 외부 파일에서 옵션 값들을 읽어서 사용하려면 forRoot
메서드가 아닌 forRootAsync
메서드를 사용한다는 것을 알게 되었다.
forRootAsync
메서드를 사용하는 경우는 다음과 같다고 한다.
결국 SequelizeModule 옵션 설정이 외부 모듈과 외부 서비스인 ConfigModule과 ConfigService에 의존하므로 forRootAsync 메서드를 사용해야 한다고 이해하였다.
먼저 앱모듈을 수정하였다.
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { ConfigModule } from '@nestjs/config';
import { sequelizeConfig } from './config/sequelize.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: `${__dirname}/config/env/.${process.env.NODE_ENV}.env`,
}),
SequelizeModule.forRootAsync(sequelizeConfig),
],
controllers: [],
providers: [],
})
export class AppModule {}
그리고 sequelize.config 파일을 다음과 같이 수정하였다.
import { ConfigModule, ConfigService } from '@nestjs/config';
import { SequelizeModuleAsyncOptions } from '@nestjs/sequelize';
export const sequelizeConfig: SequelizeModuleAsyncOptions = {
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
const options = {
dialect: configService.get('DATABASE_DIALECT'),
host: configService.get('DATABASE_HOST'),
port: configService.get('DATABASE_PORT'),
username: configService.get('DATABASE_USERNAME'),
password: configService.get('DATABASE_PASSWORD'),
database: configService.get('DATABASE_DATABASE'),
models: [__dirname + '/../**/*.model.*'],
autoLoadModels: configService.get('DATABASE_AUTOLOADMODELS'),
synchronize: configService.get('DATABASE_SYNCHRONIZE'),
};
console.log(options);
return options;
},
};
결과적으로 이 과정을 통해 문제를 해결할 수 있었는데, 도커 컴포즈로 실행하면 문제 없이 실행되지만 로컬에서 실행하면 문제가 해결되지 않았다. 로컬 문제는 좀 더 고민해봐야 할 것 같다.
즐겁게 읽었습니다. 유용한 정보 감사합니다.