Notice
suyeonme
[Nest.js] Type-safe하게 ConfigService로 환경변수 관리하기 본문
ConfigService를 사용하지 않는 경우
일반적으로 환경변수에 접근하는 경우. process.env로 접근하게 됩니다. 이렇게 접근하는 경우 환경변수를 사용하는데는 문제가 없지만 어떤 환경변수가 사용가능한지, 환경변수의 자료형은 어떤값인지등 확인이 어렵습니다.
process.env.JWT_SECRET_KEY
ConfigService를 사용해서 환경 변수를 관리해보자!
ConfigService란?
ConfigService는 환경 변수와 애플리케이션 설정 값을 런타임에 접근하고 관리하기 위한 서비스입니다. 이 서비스를 사용하면, .env 파일이나 다른 구성 소스에서 정의된 환경 설정 값을 안전하게 읽어올 수 있습니다. ConfigModule.forRoot() 또는 ConfigModule.forFeature() 메소드와 함께 사용되어, 모듈별 또는 전역 설정을 로드하고 관리할 수 있습니다.=
src/config/app.config.ts 생성
@nestjs/config의 registerAs 함수를 이용하여 config 함수를 만들어서 사용하면 다양한 종류의 환경변수를 그룹화할 수 있습니다. 이러한 그룹화는 가독성을 올리고 환경변수의 종류가 많아질 경우 구분을 수월하게 합니다.
- 모듈 위치: config의 종류가 많아질 수 있으므로 src/config/app.config.ts에 저장
// app.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('app', () => ({
jwt: {
secretKey: process.env.JWT_SECRET_KEY,
accessSecret: process.env.JWT_ACCESS_SECRET,
refreshSecret: process.env.JWT_REFRESH_SECRET,
accessExpireTime: process.env.JWT_ACCESS_EXPIRE_TIME,
refreshExpireTime: process.env.JWT_REFRESH_EXPIRE_TIME
},
throttle: {
timeToLiveMilliSec: process.env.TIME_TO_LIVE_MILLISEC,
limitRequestTimeToLive: parseInt(process.env.LIMIT_REQUEST_TIME_TO_LIVE)
},
}));
AppModule에서 환경변수 config 파일 로드
import { Module, ValidationPipe } from '@nestjs/common';
import { APP_GUARD, APP_PIPE } from '@nestjs/core';
import { ConfigModule, ConfigService } from '@nestjs/config';
// 생성한 환경변수 config 파일들
import appConfig from '@config/app.config';
import dbConfig from '@config/db.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: `.${process.env.NODE_ENV}.env`,
load: [appConfig, dbConfig] // * 여러개의 config를 로드할 수 있다.
}),
...
],
controllers: [],
providers: [
{
provide: APP_PIPE,
useClass: ValidationPipe
},
{
provide: APP_GUARD,
useClass: ThrottlerGuard
}
]
})
export class AppModule {}
Service에서 환경변수 사용하기
@Injectable()
export class AuthService {
constructor(
@Inject(appConfig.KEY)
private config: ConfigType<typeof appConfig>
) {}
const signup = () => {
...
const refreshSecret = this.config.jwt.refreshSecret; // *
}
}
config의 타입을 appConfig로 설정해줌으로써 type-checking이 가능해졌습니다. 만약 유효하지 않는 값에 접근하려고 하는 경우 에러가 표시됩니다.
또한 typescript의 장점중 하나인 입력가능한 필드 추천도 가능해집니다.
Module에서 환경변수 사용하기
forFeature의 역할
forFeature는 ConfigModule에 특정 설정 파일(appConfig)을 등록합니다. 이렇게 등록된 설정은 해당 모듈 내에서 ConfigService를 통해 접근할 수 있으며 등록된 설정은 forFeature를 호출한 모듈 내에서만 사용할 수 있습니다.
@Module({
imports: [
JwtModule.registerAsync({
imports: [ConfigModule.forFeature(appConfig)],
inject: [ConfigService],
useFactory: (config: ConfigService) => {
return {
global: true,
secret: config.get<string>('jwt.secretKey'), // *
signOptions: { expiresIn: '60s' }
};
}
})
],
providers: [...],
controllers: [AuthController],
exports: [AuthService]
})
export class AuthModule {}
또는 아래와 같이 ConfigType<T>을 이용해서 Type-safe하게 환경변수를 가져올 수 있습니다. 만약 db.config.ts의 값을 사용하고 싶다면, configService.get('db')와 같이 입력해서 사용하면 됩니다.
JwtModule.registerAsync({
imports: [ConfigModule.forFeature(appConfig)],
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
const config: ConfigType<typeof appConfig> =
configService.get('app');
return {
global: true,
secret: config.jwt.secretKey,
signOptions: { expiresIn: '60s' }
};
}
})
'프로그래밍👩🏻💻 > Node.js' 카테고리의 다른 글
[Nest.js] nodemailer로 이메일 보내기 (1) | 2024.02.09 |
---|---|
[Nest.js] Interceptor로 응답 포맷 설정하기 (1) | 2024.02.09 |
Comments