๐ŸŽ‰ berenickt ๋ธ”๋กœ๊ทธ์— ์˜จ ๊ฑธ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๐ŸŽ‰
Back
NestJs
05-Module-Provider-IoC

1. DI & IoC

  • DI(Dependency Injection, ์˜์กด์„ฑ ์ฃผ์ž…)
  • IoC(Inversion of Control, ์ œ์–ด์˜ ์—ญ์ „)

1.1 ์ผ๋ฐ˜ ์ธ์Šคํ„ด์Šคํ™”

1
class B {}
2
3
class A {
4
const b = B();
5
}

ํด๋ž˜์Šค B๋ฅผ ํด๋ž˜์Šค A์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

  • ํด๋ž˜์Šค A์•ˆ์— ํด๋ž˜์Šค B์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งค๋ฒˆ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค.
  • ์ด ๊ตฌ์กฐ๋Š” A ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•  ๋–„๋งˆ๋‹ค,
    • A์•ˆ์—๋‹ค B์ธ์Šคํ„ด์Šค๋ฅผ ๋งค๋ฒˆ ์ƒˆ๋กœ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค.

1.2 Dependency Injection

1
class B {}
2
3
class A {
4
constructor(instance: B)
5
}

๊ธฐ์กด์—๋Š” ํด๋ž˜์Šค B๋ฅผ ํด๋ž˜์Šค A ์•ˆ์—์„œ ์ƒ์„ฑํ–ˆ๋Š”๋ฐ, DI๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

  • ์–ด๋””์„ ๊ฐ€ ํด๋ž˜์Šค B๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํด๋ž˜์Šค A์—์„œ๋Š” ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ์–ด๋””์„ ๊ฐ€ ๋งŒ๋“  ํด๋ž˜์Šค B๋Š” constructor์— ์ž…๋ ฅํ•œ๋‹ค.
    • ์ด๋ฅผ ์ฃผ์ž…(Injection)์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • ํด๋ž˜์Šค A๋Š” ํด๋ž˜์Šค B๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํด๋ž˜์ŠคB์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค.
    • ์ด๋ฅผ Dependency(์˜์กด)์ด๋ผ ํ•œ๋‹ค.
  • ์ฆ‰, ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๊ฐ’์„ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๊ฒƒ์„ DI๋ผ๊ณ  ํ•œ๋‹ค.

1.3 Inversion of Control

1
class B {}
2
3
class A {
4
constructor(instance: B)
5
}
6
7
class C {
8
constructor(instance: B)
9
}

IoC๋Š” DI์˜ ์ผ์ข…์ด๋ผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • Control(์ œ์–ด)์˜ Inversion(์—ญ์ „), ์—ญ์ œ์–ด
  • ์›๋ž˜๋Š” A, C๊ฐ€ B์— ์˜์กด์„ฑ์ด ์žˆ์œผ๋ฉด, ํด๋ž˜์Šค B๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•ด์„œ ์ฃผ์ž…ํ•œ๋‹ค.
  • ๋ฐ˜๋ฉด์— IoC๋Š” A, C๊ฐ€ ์˜์กดํ•˜๋Š” B์™€ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ, ์‚ญ์ œ, ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๊ณผ์ •์„ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ง์ ‘ ๋‹ด๋‹นํ•˜๊ฒŒ ๋œ๋‹ค.

1.4 IoC & DI

Ioc-DI

NestJS๋Š” ์‹คํ–‰๊ณผ ๋™์‹œ์— IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

  • A, C๋ฅผ ๋ณด๋ฉด, B์— ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๊ณ  ์žˆ๋‹ค.
  • NestJS IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํด๋ž˜์Šค B๋ฅผ ์ด์šฉํ•ด,
    • new B()๋ฅผ ์‚ฌ์šฉํ•ด B ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค
  • A, C ํด๋ž˜์Šค ์•ˆ์—์„œ B ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•˜๋ฉด,
    • IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ B ์ธ์Šคํ„ด์Šค๋ฅผ ์ฃผ์ž…ํ•œ๋‹ค.
  • ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœ์ž๋Š” ์˜์กด์„ฑ์˜ ์ƒ์„ฑ๊ณผ ํ๊ธฐ๋ฅผ ์‹ ๊ฒฝ์“ธ ํ•„์š”๊ฐ€ ์—†๋‹ค.

NestJS์—์„œ A, C๋Š” controller, B๋Š” service๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ฒ ์ฃ .

์ฃผ์ž…์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค(service)๋ฅผ NestJS์—์„œ๋Š” Provider๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

  • Provider๋ฅผ constructor ์•ˆ์— ์ •์˜ํ•ด์ฃผ๋ฉด IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ž๋™์œผ๋กœ
  • ์ด Provider๋“ค์„ ์ฐพ์•„์„œ ์ธ์Šคํ„ด์Šคํ™”ํ•œ๋‹ค์Œ
  • ์ด ์ธ์Šคํ„ด์Šค๋ฅผ ํ•„์š”ํ•˜๋Š” ๊ณณ์— ์ฃผ์ž…ํ•ด์ค€๋‹ค.

2. Module, Provider, IoC

contoller ํŒŒ์ผ์—์„œ service์˜ ๊ธฐ๋Šฅ์„ ์–ด๋–ป๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์„๊นŒ? module ํŒŒ์ผ์„ ๋ณด๋ฉด 2๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›๊ณ  ์žˆ๋‹ค.

posts.module.ts
1
import { Module } from '@nestjs/common'
2
import { PostsService } from './posts.service'
3
import { PostsController } from './posts.controller'
4
5
@Module({
6
/** ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์‚ฌ์šฉํ•  ํŒŒ์ผ์„ ์ •์˜
7
* ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์‚ฌ์šฉํ•  ํŒŒ์ผ์„ ์ •์˜,
8
* ํŠน์ • path๋กœ ์š”์ฒญ์ด ์˜ค๋ฉด ๋ผ์šฐํŒ…ํ•ด์ฃผ๋Š” ์—ญํ• 
9
*
10
* PostsController() ===> ์ธ์Šคํ„ด์Šคํ™”
11
* PostsController ===> ํด๋ž˜์Šค ๊ทธ ์ž์ฒด
12
* ์ž˜ ๋ณด๋ฉด, ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค ๊ทธ ์ž์ฒด๋ฅผ ๋„ฃ์—ˆ๋‹ค
13
* ์™œ๋ƒํ•˜๋ฉด IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œํ•˜๊ธธ ๋ฐ”๋ผ๋‹ˆ๊นŒ
14
*/
15
controllers: [PostsController],
16
/** ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฃผ์ž…ํ•  ๊ฐ’๋“ค์„ providers ์•ˆ์— ์ •์˜
17
* PostsService๋Š” ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ •์˜๋‹ค.
18
* ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•˜๋Š” ํด๋ž˜์Šค === Service
19
*
20
* ์„œ๋น„์Šค๊ฐ€ ์•„๋‹ˆ๋”๋ผ๋„ ์ฃผ์ž…ํ•ด์•ผํ•  ํด๋ž˜์Šค๋“ค์€
21
* ์ „๋ถ€ providers ์•ˆ์— ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
22
*
23
* porviders ์•ˆ์— ๋“ฑ๋ก๋œ ๋ชจ๋“  ํด๋ž˜์Šค๋“ค์€ ์ธ์Šคํ„ด์Šคํ™” ์—†์ด
24
* IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์˜์กดํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
25
*/
26
providers: [PostsService],
27
})
28
export class PostsModule {}

๋˜ํ•œ service์—๋‹ค๊ฐ€ @Injectable()์„ ํ•ด์ค˜์•ผ์ง€๋งŒ Provider๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

posts.service.ts
1
// posts.service.ts
2
import { Injectable, NotFoundException } from '@nestjs/common'
3
4
// ์ƒ๋žต
5
6
// @Injectable() ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ์–ด์•ผ์ง€๋งŒ, Provider๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
7
@Injectable()
8
export class PostsService {
9
// ์ƒ๋žต
10
}

3. AppModule, main.ts

app.module.ts
1
import { Module } from '@nestjs/common'
2
import { AppController } from './app.controller'
3
import { AppService } from './app.service'
4
import { PostsModule } from './posts/posts.module'
5
6
@Module({
7
imports: [PostsModule],
8
controllers: [AppController],
9
providers: [AppService],
10
})
11
export class AppModule {}

NestJS๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ชจ๋“ˆ๋“ค์„ ๋ ˆ๊ณ ์ฒ˜๋Ÿผ ์กฐํ•ฉํ•ด์„œ ํ•ฉ์นœ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ CLI๋กœ ์ƒ์„ฑํ•˜๋‹ˆ ์ž๋™์œผ๋กœ AppModule์— ์ถ”๊ฐ€๋œ๋‹ค. ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์„ ์ƒˆ๋กœ ๋งŒ๋“ค๋ฉด imports ๋ถ€๋ถ„์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.


3.1 main.ts

NestJS๊ฐ€ app ๋ชจ๋“ˆ์ด ์กด์žฌํ•˜๋Š” ๊ฑธ ์•„๋Š” ๊ฑด main.ts๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋‹ค.

main.ts
1
import { NestFactory } from '@nestjs/core'
2
import { AppModule } from './app.module'
3
4
async function bootstrap() {
5
const app = await NestFactory.create(AppModule)
6
await app.listen(3000)
7
}
8
bootstrap()

์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, NestFactory์— App ๋ชจ๋“ˆ์„ ๋„ฃ์–ด์ฃผ๊ณ  ์žˆ๊ณ , 3000๋ฒˆ ํฌํŠธ์—์„œ ์‹คํ–‰ํ•˜๊ณ  ์žˆ๋‹ค.