ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

์–ด๋Š ์–ธ์–ด์ด๋˜๊ฐ„์— ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’, ์ฆ‰ configuration ์ด๋ผ๋Š” ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, Nest.js์—์„œ๋„ configuration ๋ชจ๋“ˆ์„ ์ œ๊ณตํ•ด์ฃผ๊ณ ์žˆ์œผ๋ฉฐ, ํ•ด๋‹น ๋ชจ๋“ˆ์€ dotenv ๋ชจ๋“ˆ์„ ๊ธฐ๋ฐ˜ํ•ด์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผํ•  ๋ณ€์ˆ˜ ๊ฐ’์ด๊ฑฐ๋‚˜ ํ˜น์€ ๊ฐœ๋ฐœ๋ ˆ๋ฒจ (ํ”„๋กœ๋•์…˜, ๊ฐœ๋ฐœ, ํ…Œ์ŠคํŒ… ๋“ฑ๋“ฑ..) ์— ๋”ฐ๋ฅธ ๋‹ค๋ฅธ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์œผ๋ฏ€๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„ ์…‹ํŒ…ํ•˜๊ฒŒ ๋˜๋Š” ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค. ์ด์ „์— ํฌ์ŠคํŒ…ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์ •๋ณด๊ฐ™์€ ๊ฒฝ์šฐ๋„ config ํŒŒ์ผ๋กœ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„์„œ ํ•ด๋‹น ๋ชจ๋“ˆ์„ ๋จผ์ € ์…‹ํŒ…ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

 

1. @nestjs/config ๋ชจ๋“ˆ ์ธ์Šคํ†จ

$ npm i --save @nestjs/config
or
$ yarn add @nestjs/config

nestjs์—์„œ ๊ณต์‹์œผ๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” ๋ชจ๋“ˆ์„ ์ธ์Šคํ†จํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ํŒจํ‚ค์ง€๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์œ„์— ๋ง์”€๋“œ๋ ธ๋‹ค์‹œํ”ผ dotenv๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

2. ๋ชจ๋“ˆ์— ์ ์šฉํ•˜๊ธฐ (Getting Started)

๊ณต์‹ ๋ฌธ์„œ์—์„œ ๊ฐ€์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ œ๊ณต(Getting Started)์—์„œ๋Š” ์ด์™€๊ฐ™์ด ๊ฐ€์ด๋“œํ•ฉ๋‹ˆ๋‹ค.

app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}

์œ„์˜ ์ฝ”๋“œ๋Š” ๊ธฐ๋ณธ ์œ„์น˜(ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ)์—์„œ .env ํŒŒ์ผ์„ ๋กœ๋“œ ๋ฐ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  .env ํŒŒ์ผ์˜ ํ‚ค/๊ฐ’ ์Œ์„ process.env์— ํ• ๋‹น๋œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜์™€ ๋ณ‘ํ•ฉํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๊ฐœ์ธ ๊ตฌ์กฐ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

@nestjs/config๋Š” dotenv์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ด๋ฆ„์˜ ์ถฉ๋Œ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ํŒจํ‚ค์ง€์˜ ๊ทœ์น™์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ‚ค๊ฐ€ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์— ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ(์˜ˆ: export DATABASE_USER=test์™€ ๊ฐ™์€ OS ์…ธ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ํ†ตํ•ด) ๋ฐ .env ํŒŒ์ผ์— ์žˆ๋Š” ๊ฒฝ์šฐ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค.

 
์ฆ‰, bash_profile ํ˜น์€ bashrc ์™€ ๊ฐ™์€ ํŒŒ์ผ์— ์ด๋ฏธ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •์ด ๋˜์–ด์žˆ๋”๋ผ๋„, ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ์žˆ๋Š” .env ํŒŒ์ผ์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’์ด ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋” ๋†’์Šต๋‹ˆ๋‹ค.
 

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ฐ€์ด๋“œ ๋ฐฉ๋ฒ•์ด ์žˆ๊ณ , ์ €๋Š” ์• ์ดˆ์— ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘์‹œ์— DB๋ฅผ ์—ฐ๋™์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์—
DB module์—์„œ config๋ฅผ ๋กœ๋“œํ•˜๊ณ , ๊ทธ ์ดํ›„์— ๋กœ๋“œ๋œ config ๊ฐ’์„ ๊ฐ€์ง€๊ณ  DB ์—ฐ๊ฒฐ์„ ๋จผ์ € ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

3.  DB ๋ชจ๋“ˆ ์ž‘์„ฑ

src/common/db.module.ts
import { Module } from '@nestjs/common';
import {ConfigModule, ConfigService} from '@nestjs/config';
import configuration from '@Common/configuration';
import {TypeOrmModule} from '@nestjs/typeorm';
import * as Joi from 'joi';

@Module({
    imports: [
        ConfigModule.forRoot({
            isGlobal: true,
            load: [configuration],
            envFilePath: process.env.NODE_ENV == 'local' ? '.env' : process.env.NODE_ENV == 'development' ? '.env.development' : '.env.production',
            validationSchema: Joi.object({ // ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์œ ํšจ์„ฑ ์ฒดํฌ
                NODE_ENV: Joi.string().valid('local','development', 'production', 'testing', 'staging').required(),
                DATABASE_HOST: Joi.string().required(),
                DATABASE_PORT: Joi.string().required(),
                DATABASE_USER: Joi.string().required(),
                DATABASE_PASSWORD: Joi.string().required(),
                DATABASE_NAME: Joi.string().required(),
            })
        }),
        TypeOrmModule.forRootAsync({
            imports: [ConfigModule],
            inject: [ConfigService],
            useFactory: async (configService: ConfigService) => ({
                type: 'mysql',
                host: configService.get('database.host'),
                port: configService.get('database.port'),
                username: configService.get('database.user'),
                password: configService.get('database.password'),
                database: configService.get('database.name'),
                legacySpatialSupport: false,
                logging: true,
                acquireTimeout: 5000,
                charset: 'UTF8MB4_GENERAL_CI',
                entities: ['dist/**/*.entity.{ts,js}'], // Entity ์—ฐ๊ฒฐ
                synchronize: false, //true ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ์‹คํ–‰ํ•  ๋•Œ ์—”ํ‹ฐํ‹ฐ์•ˆ์—์„œ ์ˆ˜์ •๋œ ์ปฌ๋Ÿผ์˜ ๊ธธ์ด ํƒ€์ž… ๋ณ€๊ฒฝ๊ฐ’๋“ฑ์„ ํ•ด๋‹น ํ…Œ์ด๋ธ”์„ Dropํ•œ ํ›„ ๋‹ค์‹œ ์ƒ์„ฑ
                extra: {
                    connectionLimit: configService.get('CONNECTION_LIMIT')
                }
            }),
        }),
    ],
})
export class DatabaseModule {}

์ด์ „์— ๋ฃจํŠธ๋ชจ๋“ˆ์—์„œ ConfigModule์„ ์ด์šฉํ•ด config๊ฐ’์„ ๋กœ๋“œํ•˜๋ฉด ConfigService๋ฅผ ์ฃผ์ž…๋ฐ›์„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ทธ ์ดํ›„์—๋Š” ConfigService ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด config์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

envFilePath๋ฅผ ํ†ตํ•ด NODE_ENV๊ฐ’์— ๋”ฐ๋ฅธ ์ฐธ์กฐ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ๋‹ค๋ฅด๊ฒŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

.env
# #MYSQL
DATABASE_HOST = localhost
DATABASE_USER = root
DATABASE_NAME = store
DATABASE_PASSWORD = root
DATABASE_PORT = 3306
DATABASE_LOGGING = true
CONNECTION_LIMIT=15

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ์ด์™€๊ฐ™์ด env ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๋ฉด ConfigModule์—์„œ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ์žˆ๋Š” ํ•ด๋‹น ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

 

4. ๋ฃจํŠธ๋ชจ๋“ˆ์— DB๋ชจ๋“ˆ import ๋ฐ ํƒ€ ๋ชจ๋“ˆ์—์„œ configService ์‚ฌ์šฉ

DB ์—ฐ๊ฒฐ์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ์— ํ•„์š”ํ•˜๊ธฐ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด import ํ•ฉ๋‹ˆ๋‹ค.

app.module.ts
import { DatabaseModule } from '@Common/db.module';
import { Module } from '@nestjs/common';
import { OrderModule } from '@Order/order.module';
import {TypeOrmModule} from '@nestjs/typeorm';

@Module({
    imports: [
        DatabaseModule,
        TypeOrmModule.forFeature([]),
        OrderModule,
    ]
})
export class AppModule {}

DatabaseModule์„ ๋ชป๊ฐ€์ ธ์˜ค๋ฉด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์—๋Ÿฌ๊ฐ€ ๋–จ์–ด์งˆ๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๋ชจ๋“ˆ์—์„œ ConfigModule๋„ ๊ฐ™์ด importํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ์ •์ƒ์‹คํ–‰๋๋‹ค๋ฉด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ๋„ ConfigService๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

src/order/services/order.service.ts
import { Injectable } from '@nestjs/common';
import {ConfigService} from '@nestjs/config';

@Injectable()
export class OrderService {
    constructor(
      private readonly config: ConfigService
    ) {
        console.log(config.get("database.host"))
    }
}

๋ฌผ๋ก  ์—ฌ๊ธฐ์„œ ์ € config๊ฐ’์ด ํ•„์š”ํ•œ๊ฑด ์•„๋‹ˆ์ง€๋งŒ ์œ„์™€๊ฐ™์ด ConfigService๋ฅผ ๋ฐ”๋กœ ์ฃผ์ž…๋ฐ›์•„์„œ config ๊ฐ’์„ ์ฐธ์กฐ ๊ฐ€๋Šฅํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

๋Œ“๊ธ€
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
ยซ   2024/11   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
๊ธ€ ๋ณด๊ด€ํ•จ