๐Ÿ“‘ ๊ณต์‹ ๋ฌธ์„œ ๋ฒˆ์—ญ/Nest.js

[Nest.js] Fundamentals - Custom providers, Asynchronous providers

dev_writer 2025. 7. 15. 00:15

์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋”

์•ž์„  ์ฑ•ํ„ฐ๋“ค์—์„œ๋Š” Nest์—์„œ์˜ ์˜์กด์„ฑ ์ฃผ์ž… (Dependency Injection, DI)์˜ ๋‹ค์–‘ํ•œ ์ธก๋ฉด๊ณผ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋‹ค๋ฃจ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์ค‘ ํ•˜๋‚˜๋Š” ํด๋ž˜์Šค์— ์ธ์Šคํ„ด์Šค (๋Œ€๊ฐœ ์„œ๋น„์Šค ํ”„๋กœ๋ฐ”์ด๋”)๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜ ์˜์กด์„ฑ ์ฃผ์ž…์ž…๋‹ˆ๋‹ค. ์˜์กด์„ฑ ์ฃผ์ž…์ด Nest์˜ ํ•ต์‹ฌ์— ๊ทผ๋ณธ์ ์œผ๋กœ ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์€ ์ด์ œ ๋” ์ด์ƒ ๋†€๋ž์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€๋Š” ์ฃผ๋กœ ํ•˜๋‚˜์˜ ์ฃผ์š” ํŒจํ„ด๋งŒ ์‚ดํŽด๋ณด์•˜์ง€๋งŒ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก DI ์‹œ์Šคํ…œ์˜ ์ „์ฒด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด๋ฅผ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

DI์˜ ๊ธฐ๋ณธ ์›๋ฆฌ

์˜์กด์„ฑ ์ฃผ์ž…์€ ์ œ์–ด์˜ ์—ญ์ „ (Inversion of Control, IoC) ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ, ์˜์กด์„ฑ์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์„ ๊ฐœ๋ฐœ์ž ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ IoC ์ปจํ…Œ์ด๋„ˆ (์—ฌ๊ธฐ์„œ๋Š” NestJS ๋Ÿฐํƒ€์ž„ ์‹œ์Šคํ…œ)์— ์œ„์ž„ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. Providers ์ฑ•ํ„ฐ์—์„œ ๋ณด์•˜๋˜ ์˜ˆ์ œ๋ฅผ ๋‹ค์‹œ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋จผ์ €, ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. @Injectable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” CatsService ํด๋ž˜์Šค๋ฅผ ํ”„๋กœ๋ฐ”์ด๋”๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}

 

๊ทธ๋‹ค์Œ, Nest๊ฐ€ ํ•ด๋‹น ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์šฐ๋ฆฌ์˜ ์ปจํŠธ๋กค๋Ÿฌ ํด๋ž˜์Šค์— ์ฃผ์ž…ํ•˜๋„๋ก ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค:

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}

 

๋งˆ์ง€๋ง‰์œผ๋กœ, ํ•ด๋‹น ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ Nest IoC ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค:

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}

 

์ด ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š” ๊ฑธ๊นŒ์š”? ์ด ๊ณผ์ •์—๋Š” ์„ธ ๊ฐ€์ง€ ํ•ต์‹ฌ ๋‹จ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

  1. cats.service.ts์—์„œ @Injectable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” CatsService ํด๋ž˜์Šค๋ฅผ Nest IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
  2. cats.controller.ts์—์„œ CatsController๋Š” ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ํ†ตํ•ด CatsService ํ† ํฐ์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
  3. app.module.ts์—์„œ CatsService ํ† ํฐ์„ cats.service.ts ํŒŒ์ผ์˜ CatsService ํด๋ž˜์Šค์™€ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด ์—ฐ๊ฒฐ ๊ณผ์ •์€ ์•„๋ž˜์—์„œ ๋ณด๊ฒŒ ๋  ๋“ฑ๋ก (registration) ๊ณผ์ •์˜ ์ผํ™˜์ž…๋‹ˆ๋‹ค.
  constructor(private catsService: CatsService)

 

Nest IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ CatsController๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•  ๋•Œ, ๋จผ์ € ํ•ด๋‹น ํด๋ž˜์Šค์˜ ๋ชจ๋“  ์˜์กด์„ฑ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. CatsService ์˜์กด์„ฑ์„ ๋ฐœ๊ฒฌํ•˜๋ฉด, ์œ„์˜ 3๋‹จ๊ณ„ ๋“ฑ๋ก ๊ณผ์ •์— ๋”ฐ๋ผ CatsService ํ† ํฐ์„ ์กฐํšŒํ•˜์—ฌ CatsService ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋™์ž‘์ธ SINGLETON ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ •ํ•˜๋ฉด, Nest๋Š” CatsService ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ ์บ์‹ฑํ•œ ๋’ค ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜, ์ด๋ฏธ ์บ์‹ฑ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

*์ด ์„ค๋ช…์€ ๊ฐœ๋…์„ ์‰ฝ๊ฒŒ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ์•ฝ๊ฐ„ ๋‹จ์ˆœํ™”๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ค‘์š”ํ•œ ๋ถ€๋ถ„ ์ค‘ ํ•˜๋‚˜๋Š” ์˜์กด์„ฑ์„ ๋ถ„์„ํ•˜๋Š” ๊ณผ์ •์ด ๋งค์šฐ ์ •๊ตํ•˜๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ์‹œ์ ์— ์ด๋ฃจ์–ด์ง„๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ํ•ต์‹ฌ์ ์ธ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” ์ด ์˜์กด์„ฑ ๋ถ„์„ (๋˜๋Š” "์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ")์ด ์ „์ด์ ์ด๋ผ๋Š” ใ…ˆ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ„์˜ ์˜ˆ์‹œ์—์„œ CatsService ์ž์ฒด์— ๋˜ ๋‹ค๋ฅธ ์˜์กด์„ฑ์ด ์žˆ๋‹ค๋ฉด, Nest๋Š” ๊ทธ๊ฒƒ๋“ค๋„ ํ•จ๊ป˜ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„๋Š” ๋ชจ๋“  ์˜์กด์„ฑ์ด ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ (๋ณธ์งˆ์ ์œผ๋กœ "ํ•˜ํ–ฅ์‹")๋กœ ํ•ด๊ฒฐ๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•๋ถ„์— ๊ฐœ๋ฐœ์ž๋Š” ๋ณต์žกํ•œ ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

ํ‘œ์ค€ ํ”„๋กœ๋ฐ”์ด๋”

@Module() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ข€ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. app.module์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค:

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})

 

providers ์†์„ฑ์€ ํ”„๋กœ๋ฐ”์ด๋”๋“ค์˜ ๋ฐฐ์—ด์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€๋Š” ํด๋ž˜์Šค ์ด๋ฆ„ ๋ชฉ๋ก์„ ํ†ตํ•ด ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ œ๊ณตํ•ด ์™”์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ providers: [CatsService]๋ผ๋Š” ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋” ์™„์ „ํ•œ ๋ฌธ๋ฒ•์˜ ์ถ•์•ฝ์ž…๋‹ˆ๋‹ค.

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];

 

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

์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋”

๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ์ด ํ‘œ์ค€ ํ”„๋กœ๋ฐ”์ด๋” (Standard providers)๋กœ๋Š” ์ถฉ์กฑ๋˜์ง€ ์•Š์„ ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ๋‹ค์Œ์€ ๊ทธ๋Ÿฐ ์‚ฌ๋ก€๋“ค์ž…๋‹ˆ๋‹ค:

  • Nest๊ฐ€ ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๊ฑฐ๋‚˜ ์บ์‹œ ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹ , ์ง์ ‘ ์ปค์Šคํ…€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • ๊ธฐ์กด ํด๋ž˜์Šค๋ฅผ ๋‹ค๋ฅธ ์˜์กด์„ฑ์—์„œ ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ํด๋ž˜์Šค๋ฅผ ๋ชจํ‚น (mock)ํ•œ ๋ฒ„์ „์œผ๋กœ ๋Œ€์ฒดํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ

Nest๋Š” ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋” (Custom providers)๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ์ •์˜ ๋ฐฉ๋ฒ•๋„ ํ•จ๊ป˜ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๊ฐ ๋ฐฉ์‹์„ ํ•จ๊ป˜ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํžŒํŠธ
์˜์กด์„ฑ ํ•ด๊ฒฐ ๊ณผ์ •์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด, NEST_DEBUG ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ์˜์กด์„ฑ ํ•ด๊ฒฐ ๋กœ๊ทธ๋ฅผ ์ถ”๊ฐ€๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ’ ํ”„๋กœ๋ฐ”์ด๋”: useValue

useValue ๋ฌธ๋ฒ•์€ ์ƒ์ˆ˜ ๊ฐ’์„ ์ฃผ์ž…ํ•˜๊ฑฐ๋‚˜, ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ Nest ์ปจํ…Œ์ด๋„ˆ์— ๋„ฃ๊ฑฐ๋‚˜, ์‹ค์ œ ๊ตฌํ˜„์ฒด๋ฅผ ๋ชฉ ๊ฐ์ฒด๋กœ ๋Œ€์ฒดํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด Nest๊ฐ€ ๋ชฉ์—… ๋œ CatsService๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฐ•์ œํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค.

import { CatsService } from './cats.service';

const mockCatsService = {
  /* ๋ชฉ์—… ๊ตฌํ˜„
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}

 

์ด ์˜ˆ์ œ์—์„œ CatsService ํ† ํฐ์€ mockCatsService ๋ชฉ ๊ฐ์ฒด๋กœ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. useValue๋Š” ๊ฐ’์„ ์š”๊ตฌํ•˜๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ ๋Œ€์ฒดํ•˜๋ ค๋Š” CatsService ํด๋ž˜์Šค์™€ ๋™์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง„ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. TypeScript์˜ ๊ตฌ์กฐ์  ํƒ€์ดํ•‘ (Structural Typing) ๋•๋ถ„์—, ํ˜ธํ™˜๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋ผ๋ฉด ์–ด๋–ค ๊ฒƒ์ด๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฆฌํ„ฐ๋Ÿด ๊ฐ์ฒด๋Š” ๋ฌผ๋ก  new๋กœ ์ƒ์„ฑํ•œ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋น„ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ํ”„๋กœ๋ฐ”์ด๋” ํ† ํฐ

์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๋Š” ํด๋ž˜์Šค ์ด๋ฆ„์„ ํ”„๋กœ๋ฐ”์ด๋” ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉํ•ด ์™”์Šต๋‹ˆ๋‹ค (providers ๋ฐฐ์—ด ๋‚ด provide ์†์„ฑ์˜ ๊ฐ’). ์ด๋Š” ์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜ ์ฃผ์ž…์—์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํŒจํ„ด๊ณผ ์ผ์น˜ํ•˜๋ฉฐ, ์ด ๊ฒฝ์šฐ ํ† ํฐ ์—ญ์‹œ ํด๋ž˜์Šค ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. (ํ† ํฐ ๊ฐœ๋…์ด ์™„์ „ํžˆ ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์•ž์„œ ์„ค๋ช…ํ•œ DI ๊ธฐ๋ณธ ๋‚ด์šฉ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.) ํ•˜์ง€๋งŒ ๋•Œ๋กœ๋Š” ๋ฌธ์ž์—ด์ด๋‚˜ ์‹ฌ๋ณผ์„ DI ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์œ ์—ฐ์„ฑ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

import { connection } from './connection';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}

 

์ด ์˜ˆ์ œ์—์„œ๋Š” ๋ฌธ์ž์—ด ํ† ํฐ 'CONNECTION'์„ ์™ธ๋ถ€ ํŒŒ์ผ์—์„œ ๊ฐ€์ ธ์˜จ ๊ธฐ์กด์˜ ์ปค๋„ฅ์…˜ ๊ฐ์ฒด์™€ ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์•Œ๋ฆผ
๋ฌธ์ž์—ด ์™ธ์—๋„ JavaScript ์‹ฌ๋ณผ์ด๋‚˜ TypeScript ์—ด๊ฑฐํ˜• (enum)์„ ํ† ํฐ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์•ž์„œ ์šฐ๋ฆฌ๋Š” ํ‘œ์ค€ ์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜ ์ฃผ์ž… ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์—์„œ๋Š” ์˜์กด์„ฑ์„ ํด๋ž˜์Šค ์ด๋ฆ„์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, 'CONNECTION' ์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋”๋Š” ๋ฌธ์ž์—ด ํ† ํฐ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ฃผ์ž…ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ์ด๋ฅผ ์œ„ํ•ด @Inject() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ๋Š” ํ† ํฐ์„ ์ธ์ž๋กœ ํ•˜๋‚˜ ๋ฐ›์Šต๋‹ˆ๋‹ค.

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
ํžŒํŠธ
@Inject() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” @nestjs/common ํŒจํ‚ค์ง€์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

 

์œ„ ์˜ˆ์ œ์—์„œ๋Š” ์„ค๋ช…์„ ์œ„ํ•ด ๋ฌธ์ž์—ด 'CONNECTION'์„ ์ง์ ‘ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ์œ„ํ•ด ํ† ํฐ์€ constants.ts์™€ ๊ฐ™์€ ๋ณ„๋„์˜ ํŒŒ์ผ์— ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ๋ชจ๋ฒ” ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‹ฌ๋ณผ์ด๋‚˜ ์—ด๊ฑฐํ˜• (enum)์„ ๋ณ„๋„ ํŒŒ์ผ์— ์ •์˜ํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ import ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋™์ผํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ํ”„๋กœ๋ฐ”์ด๋”: useClass

useClass ๋ฌธ๋ฒ•์€ ํ† ํฐ์ด ์–ด๋–ค ํด๋ž˜์Šค์— ๋งคํ•‘๋ ์ง€ ๋™์ ์œผ๋กœ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ธฐ๋ณธ ๋˜๋Š” ์ถ”์ƒ์ ์ธ ConfigService ํด๋ž˜์Šค๊ฐ€ ์žˆ๊ณ , ํ˜„์žฌ ์‹คํ–‰ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์„œ๋กœ ๋‹ค๋ฅธ ConfigService ๊ตฌํ˜„์ฒด๋ฅผ Nest๊ฐ€ ์ œ๊ณตํ•˜๋„๋ก ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ทธ๋Ÿฌํ•œ ์ „๋žต์„ ๊ตฌํ˜„ํ•œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}

 

์ด ์ฝ”๋“œ ์˜ˆ์ œ์—์„œ ๋ช‡ ๊ฐ€์ง€ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋จผ์ €, configServiceProvider๋ฅผ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ์ฒด๋กœ ๋จผ์ € ์ •์˜ํ•œ ๋’ค, ์ด๋ฅผ ๋ชจ๋“ˆ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ providers ์†์„ฑ์— ์ „๋‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋‹จ์ˆœํ•œ ์ฝ”๋“œ ๊ตฌ์„ฑ ๋ฐฉ์‹์˜ ์ฐจ์ด์ผ ๋ฟ์ด๋ฉฐ, ๊ธฐ๋Šฅ์ ์œผ๋กœ๋Š” ์ด ์žฅ์—์„œ ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ•œ ๋‹ค๋ฅธ ์˜ˆ์ œ๋“ค๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

 

๋˜ํ•œ, ์šฐ๋ฆฌ๋Š” ConfigService ํด๋ž˜์Šค ์ด๋ฆ„์„ ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ConfigService์— ์˜์กดํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ, Nest๋Š” ๋“ฑ๋ก๋œ ํด๋ž˜์Šค (DevelopmentConfigService ๋˜๋Š” ProductionConfigService)์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค๋ฅธ ๊ณณ์— ์„ ์–ธ๋œ ๊ธฐ๋ณธ ๊ตฌํ˜„ (@Injectable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์„ ์–ธ๋œ ConfigService ๋“ฑ)์„ ๋ฎ์–ด์“ฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํŒฉํ† ๋ฆฌ ํ”„๋กœ๋ฐ”์ด๋”: useFactory

useFactory ๋ฌธ๋ฒ•์€ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์‹ค์ œ ํ”„๋กœ๋ฐ”์ด๋”๋Š” ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์— ์˜ํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์ด ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋Š” ๋‹จ์ˆœํ•  ์ˆ˜๋„ ์žˆ๊ณ  ๋ณต์žกํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํ•œ ๊ฒฝ์šฐ์—๋Š” ๋‹ค๋ฅธ ํ”„๋กœ๋ฐ”์ด๋”์— ์˜์กดํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ณ , ๋ณต์žกํ•œ ๊ฒฝ์šฐ์—๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ฃผ์ž…๋ฐ›์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณต์žกํ•œ ๊ฒฝ์šฐ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด useFactory๋Š” ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ•จ๊ป˜ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

  1. ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋Š” (์„ ํƒ์ ์œผ๋กœ) ์ธ์ž๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. inject ์†์„ฑ์€ Nest๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฃผ์ž…ํ•ด์•ผ ํ•  ํ”„๋กœ๋ฐ”์ด๋” ๋ชฉ๋ก์„ ๋ฐฐ์—ด๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. Nest๋Š” ์ด ๋ชฉ๋ก์˜ ๊ฐ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ํ•ด์„ํ•ด ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ, ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๋ฉฐ, ํ•„์š”์‹œ ๊ฐ ํ•ญ๋ชฉ์„ ์„ ํƒ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์ œ๋Š” ์ด๋Ÿฌํ•œ ๋™์ž‘์„ ์ž˜ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: MyOptionsProvider, optionalProvider?: string) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [MyOptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \______________/             \__________________/
  //        ์ด ํ”„๋กœ๋ฐ”์ด๋”๋Š”              ์ด ํ† ํฐ์„ ๊ฐ€์ง„ ํ”„๋กœ๋ฐ”์ด๋”๋Š”
  //        ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.                   `undefined`๋กœ ํ•ด๊ฒฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider, // ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ํ”„๋กœ๋ฐ”์ด๋”
    // { provide: 'SomeOptionalProvider', useValue: 'anything' }, // ์„ ํƒ์  ํ”„๋กœ๋ฐ”์ด๋” ์˜ˆ์‹œ
  ],
})
export class AppModule {}

๋ณ„์นญ ํ”„๋กœ๋ฐ”์ด๋”: useExisting

useExisting ๋ฌธ๋ฒ•์€ ๊ธฐ์กด ํ”„๋กœ๋ฐ”์ด๋”์— ๋Œ€ํ•œ ๋ณ„์นญ (alias)์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์ด๋กœ์จ ํ•˜๋‚˜์˜ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ† ํฐ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์—์„œ๋Š” ๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ ํ† ํฐ 'AliasedLoggerService'๊ฐ€ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ํ† ํฐ LoggerService์˜ ๋ณ„์นญ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 'AliasedLoggerService'์™€ LoggerService ๊ฐ๊ฐ์„ ์˜์กด์„ฑ์œผ๋กœ ๊ฐ€์ง„ ๋‘ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด, ๋‘ ํ† ํฐ์ด ๋ชจ๋‘ SINGLETON ์Šค์ฝ”ํ”„๋กœ ์ง€์ •๋œ ๊ฒฝ์šฐ ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋กœ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

@Injectable()
class LoggerService {
  /* ๊ตฌํ˜„ ์ƒ์„ธ */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}

๋น„์„œ๋น„์Šค ๊ธฐ๋ฐ˜ ํ”„๋กœ๋ฐ”์ด๋”

ํ”„๋กœ๋ฐ”์ด๋”๋Š” ์ฃผ๋กœ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, ๊ทธ ์šฉ๋„์— ์ œํ•œ์€ ์—†์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๋ฐ”์ด๋”๋Š” ์–ด๋–ค ๊ฐ’์ด๋“  ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜์™€ ๊ฐ™์ด ํ˜„์žฌ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๊ตฌ์„ฑ ๊ฐ์ฒด ๋ฐฐ์—ด์„ ์ œ๊ณตํ•˜๋Š” ํ”„๋กœ๋ฐ”์ด๋”๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}

์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋” ๋‚ด๋ณด๋‚ด๊ธฐ

๋‹ค๋ฅธ ํ”„๋กœ๋ฐ”์ด๋”์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋”๋„ ์ •์˜๋œ ๋ชจ๋“ˆ ๋‚ด๋ถ€์— ํ•œ์ •๋œ ๋ฒ”์œ„ (scope)๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ด๋ฅผ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ ค๋ฉด export ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ export ํ•˜๋ ค๋ฉด ํ† ํฐ ๋˜๋Š” ์ „์ฒด ํ”„๋กœ๋ฐ”์ด๋” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋‹ค์Œ ์˜ˆ์ œ๋Š” ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ export ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}

 

๋˜๋Š”, ์ „์ฒด ํ”„๋กœ๋ฐ”์ด๋” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ export ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}

๋น„๋™๊ธฐ ํ”„๋กœ๋ฐ”์ด๋”

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— ํ•˜๋‚˜ ์ด์ƒ์˜ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์‹œ์ž‘์„ ์ง€์—ฐ์‹œ์ผœ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์š”์ฒญ์„ ๋ฐ›์ง€ ์•Š๋„๋ก ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์š”๊ตฌ๋Š” ๋น„๋™๊ธฐ ํ”„๋กœ๋ฐ”์ด๋” (Asynchronous providers)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฅผ ์œ„ํ•œ ๋ฌธ๋ฒ•์€ useFactory ๋ฌธ๋ฒ•๊ณผ ํ•จ๊ป˜ async/await์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋Š” Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ๊ทธ ์•ˆ์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ await ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Nest๋Š” ํ•ด๋‹น ํ”„๋กœ๋ฐ”์ด๋”์— ์˜์กดํ•˜๋Š” ์–ด๋–ค ํด๋ž˜์Šค๋„ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๊ธฐ ์ „์— ํ•ด๋‹น Promise๊ฐ€ ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค.

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
ํžŒํŠธ
์ปค์Šคํ…€ ํ”„๋กœ๋ฐ”์ด๋” ๋ฌธ๋ฒ•์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๋ ค๋ฉด ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

์ฃผ์ž…

๋น„๋™๊ธฐ ํ”„๋กœ๋ฐ”์ด๋”๋„ ๋‹ค๋ฅธ ์ผ๋ฐ˜ ํ”„๋กœ๋ฐ”์ด๋”๋“ค๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ† ํฐ์„ ํ†ตํ•ด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์— ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์ œ์—์„œ์ฒ˜๋Ÿผ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: @Inject('ASYNC_CONNECTION')

์˜ˆ์ œ

TypeORM ๋ ˆ์‹œํ”ผ์—๋Š” ๋น„๋™๊ธฐ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ํ™œ์šฉํ•œ ๋” ์‹ค์งˆ์ ์ธ ์˜ˆ์ œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Reference