안녕하세요! 오늘은 NestJS 프로젝트에서 환경 변수 관리를 더 효율적으로 할 수 있게 해주는 nestjs-library-config
를 소개해드리려고 합니다. 프로젝트를 진행하다 보면 .env
파일이 점점 커지면서 "이 설정값이 대체 어디서 쓰이는 거지?" 하는 고민이 생기시죠? 저도 같은 고민을 했었고, 이를 해결하기 위해 도입한 방법을 공유해보려고 합니다. 😊
기존 설정 관리의 문제점
# 점점 커져가는 .env 파일...
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USERNAME=user
DATABASE_PASSWORD=password
REDIS_HOST=localhost
REDIS_PORT=6379
AWS_ACCESS_KEY=xxxxx
AWS_SECRET_KEY=xxxxx
EMAIL_SERVICE_API_KEY=xxxxx
JWT_SECRET=xxxxx
JWT_EXPIRATION=3600
... (끝없이 늘어나는 설정값들)
이런 경험 다들 있으시죠? 🤔
- "이 환경 변수가 어디서 쓰이는지 찾기 어려워..."
- "숫자인데 문자열로 들어오네? 매번 형변환 해줘야 하나..."
- "필수값인데 누가 설정 안 해놨네... 런타임 에러 발생!"
nestjs-library-config 시작하기
먼저 라이브러리를 설치해볼까요?
npm install @woowa/nestjs-library-config
AbstractConfigService - 설정 관리의 핵심 🔧
가장 먼저 이해해야 할 것은 AbstractConfigService
입니다. 이 친구가 우리의 설정 관리를 편하게 만들어주는 핵심이에요!
"AbstractConfigService가 뭐가 좋은데요?" 🤔
다음과 같은 편리한 기능들을 모두 자동으로 제공합니다:
자동화된 초기화
- 환경 변수 로드
- 설정값 매핑
- 값 변환
- 유효성 검증
타입 안정성 보장
- 컴파일 타임에 타입 체크
- IDE 자동 완성 지원
확장 가능한 구조
- 필요한 경우 커스텀 검증 로직 추가 가능
실전: 알림 서비스 설정 구현하기
실제 예시를 통해 어떻게 사용하는지 알아볼까요?
// notification.config.service.ts
import { AbstractConfigService } from '@nestjs-library/config';
import { Injectable } from '@nestjs/common';
import { Expose, Transform } from 'class-transformer';
import { IsNotEmpty, IsString } from 'class-validator';
@Injectable()
export class NotificationConfigService extends AbstractConfigService<NotificationConfigService> {
@Expose({ name: 'KEY' })
@Transform(({ value }) => value)
@IsString()
@IsNotEmpty()
key: string;
@Expose({ name: 'USERID' })
@Transform(({ value }) => value)
@IsString()
@IsNotEmpty()
userId: string;
@Expose({ name: 'SENDERKEY' })
@Transform(({ value }) => value)
@IsString()
@IsNotEmpty()
senderKey: string;
}
모든 설정 한번에 등록하기
// app.module.ts
@Module({
imports: [
ConfigModule.register({
configList: [NotificationConfigService, JwtConfigService],
}),
// 다른 모듈들...
],
})
export class AppModule {}
비동기 설정이 필요할 때는?
JWT 모듈처럼 비동기 설정이 필요한 경우도 깔끔하게 처리할 수 있습니다:
// jwt.module.ts
@Module({
imports: [
JwtModule.registerAsync({
imports: [ConfigModule.forFeature(JwtConfigService)],
inject: [JwtConfigService],
useFactory: async (jwtConfigService: JwtConfigService) => ({
secret: jwtConfigService.jwtAccessKeySecret,
signOptions: { expiresIn: '60s' },
}),
}),
],
})
export class AuthModule {}
설정값 실제 사용하기
설정 클래스를 만들었다면, 실제 서비스에서 이렇게 사용할 수 있습니다:
// notification.service.ts
import { Injectable } from '@nestjs/common';
import { NotificationConfigService } from './notification.config.service';
@Injectable()
export class NotificationService {
constructor(
private readonly configService: NotificationConfigService,
) {}
async sendNotification(message: string) {
// 설정값들을 타입 안전하게 사용할 수 있습니다!
const apiKey = this.configService.key;
const userId = this.configService.userId;
const senderKey = this.configService.senderKey;
// 이제 이 값들을 사용해서 알림을 보내는 로직을 구현...
console.log(`Sending notification with key: ${apiKey}, userId: ${userId}`);
}
}
⭐ 실무 꿀팁!
자주 사용하는 설정값 캐싱하기
@Injectable() export class NotificationService { private readonly apiKey: string; constructor(private readonly config: NotificationConfigService) { this.apiKey = config.key; // 자주 사용하는 값은 캐싱 } }
환경별 설정 분기
@Injectable() export class EmailService { constructor(private readonly config: EmailConfigService) {} async sendEmail() { if (this.config.isTestMode) { // 테스트 환경용 로직 return; } // 실제 이메일 발송 로직 } }
정리하며 🎉
nestjs-library-config
를 도입하면서 얻은 장점들을 정리해보면:
설정값의 사용처가 명확해졌습니다
- 각 모듈별로 필요한 설정이 명시적으로 드러나요
- 어떤 설정이 어디서 사용되는지 쉽게 파악할 수 있죠
타입 안정성이 보장됩니다
- 컴파일 타임에 오류를 잡을 수 있어요
- IDE 자동 완성의 도움을 받을 수 있습니다
유효성 검증이 자동화되었습니다
- 필수값 검증이 자동으로 이루어져요
- 잘못된 타입의 값이 들어올 수 없습니다
코드 리뷰가 쉬워졌습니다
- 설정 관련 변경사항을 한눈에 파악할 수 있어요
- 각 모듈의 설정 의존성이 명확해졌죠
처음에는 "설정 관리를 이렇게까지?" 싶었지만, 프로젝트가 커질수록 이 방식이 주는 이점을 실감하게 될 거예요. 특히 여러 개발자가 함께 일하는 프로젝트에서는 더욱 빛을 발합니다! ✨
참고 자료
'개발 > NestJS' 카테고리의 다른 글
NestJS JWT 인증 시 발생하는 'secretOrPrivateKey must have value' 에러 완벽 해결하기 🔐 (1) | 2024.11.21 |
---|---|
TypeORM에서 insert() 사용 시 @BeforeInsert가 동작하지 않는 문제 해결하기 🤔 (0) | 2024.11.20 |
NestJS에서 AWS S3 파일 업로드 깔끔하게 구현하기 🚀 (0) | 2024.11.15 |
😎 NestJS class-transform 제대로 알고 쓰자! (3) | 2024.11.12 |
[NestJS] TypeORM Pagination: 설치, 사용법, 직접 구현과의 비교 with nestjs-paginate (1) | 2024.11.05 |
댓글