오히려 좋아..

상황이 나쁘게만 흘러가는 것 같을 때 외쳐보자.. .

궁금한 마음으로 포트폴리오 보기

Web Programming/NestJS

[NestJS] 아직도 dotenv 사용함?

junha6316 2022. 2. 3. 22:00

미안하다 ConfigModule 보여주려고 어그로 좀 끌었다. 일반적으로 데이터베이스의 호스트 및 유저, 비밀번호와 같은 정보는 앱내에 하드코딩해서 보관하지 않는다. 이런 정보들은 실수로라도 노출되면 서비스에 치명적인 공격으로 이어질 수 있기 떄문이다. 이런 상황을 막기 위해 일반적으로 따로 변수를 파일로 보관 후 런타임에서 가져다 사용하는 방식으로 구현한다. 이를 도와주는 대표적인 패키지가 바로 dotenv이다. dotenv가 지원하는 프레임워크가 많다. NestJS에서도 당연히 dotenv로 구현하려고 했지만 구글신에게 여쭤보니 NestJS에서 내부 패키지로 dotenv와 같은 기능을 지원하는게 있다고 한다. @nest/config 이다.

 

먼저 해당 패키지를 다운로드 해주자!

yarn add @nestjs/config // yarn을 사용하면 이것
npm install --save @nestjs/config // npm을 사용하면 이것

 

먼저 appModule에 ConfigModule을 등록해주지. 아래처럼 등록할 수 있다. 

// app.module.ts

import { ConfigModule } from "@nestjs/config";
import Joi from "joi";

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath:
        process.env.NODE_ENV === "dev" ? "./env/dev.env" : "./env/test.env",
      validationSchema: Joi.object({
        DB_USER: Joi.string().required(),
        DB_PASSWORD: Joi.string().required(),
      }),
    }),
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

envFilePath는 어떤 환경변수파일(.env 파일)을 사용할지 정하는 것으로 보통 process.env의 NODE_ENV값을 사용한다.

프로젝트 루트 디렉토리에 다음과 같은 구조로 파일을 만들어 사용가능하다.

dist
test
src
README.md
tsconfig.json
env
 |- dev.env
 |- test.env
 |- prod.env

NODE_ENV는 아래처럼 쉘(까만창)을 통해 선언 가능하다.

export NODE_ENV=dev

확인하고 싶다면 아래 명령어로 가능하다. 

echo $NODE_ENV

추가로 validationSchema는 Joi라는 패키지를 이용해 현재 환경변수 파일에 값이 정확히 들어오고 있는지 유효성 검사를 진행할 수 있다.

구현은 위에 적혀져 있다.

 

이제 환경변수 파일로 부터 가져온 값을 어떻게 사용하는지 보자. 원하는 곳에 Configservice를 inject해 사용 가능하다. 아래 예시를 통해 응용하면 된다.

 

1. Mongoose 연결

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => ({
        uri: config.get('MONGO_URL'),
        user: config.get('MONGO_USER'),
        password: config.get('MONGO_PASSWORD'),
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [],
})
export class MongoModule {}

 

2. Service에서 사용

Service에서 사용하기 위해선 먼저 module에 ConfigModule를 import 해줘야한다.

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { OrderstreamService } from './order.service';

@Module({
  imports: [ConfigModule],
  providers: [OrdermService],
  exports: [OrderService],
})
export class OrderModule {}
@Injectable()
export class OrderService {

  constructor(
    private readonly config: ConfigService,
    @InjectConnection() private connection: mongoose.Connection
  ) {
    const apiKey: string = this.config.get("TEST_API_KEY");
    const apiSecretKey: string = this.config.get("TEST_API_SECRET");
    this.client = connect(apiKey, apiSecretKey);
  }

 

도움이 되었다면 하트 ♥️