๐ NestJS์ ์์กด์ฑ ์ฃผ์ (DI)
์์กด์ฑ ์ฃผ์ ์ ๋์ ์๋ฆฌ์ ํ์์ฑNestJS์ ์์กด์ฑ ์ฃผ์ (DI), ์ ํ์ํ๊ณ ์ค์ ๋ก๋ ์ด๋ป๊ฒ ์ธ๊น
NestJS๋ฅผ ๊ณต๋ถํ๋ฉด์ ์ฒ์์ผ๋ก @Injectable()์ด๋ผ๋ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ฒ ๋์๋ค.
์๋น์ค์์@Injectable() ์ ์ฌ์ฉํ๋ฉด, Controller์ ์์์ ์ธ์คํด์ค๊ฐ ๋ค์ด์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์๋ค.
์ด๋ฌํ ๊ณผ์ ์ด ์ ํ์ํ๋ฉฐ, ์ด๋ป๊ฒ ๋์ํ๋ ์ง ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํ๋ค.
new๋ฅผ ์ ํ๋๋ฐ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์์์๊น?
this.boardsService๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ณ ์์ง๋ง, ์ฐ๋ฆฌ๋ ์ด๋์์๋ new BoardsService()๋ฅผ ํ์ง ์์๋ค. ๊ทธ๋ผ ๋๊ฐ ์ด ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด์ ๋ฃ์ด์ค ๊ฑธ๊น?
๋ต์ NestJS์ DI ์ปจํ ์ด๋๋ค. ์ ํ์ํ ์ง ๋๊ปด๋ณด๊ธฐ ์ํด nest์ ๋์์ด ์๋ค๋ ๊ฐ์ ํ์ ์๊ฐํด๋ณด์๋ค.
๋ง์ฝ ์ง์ ํด์ผ ํ๋ค๋ฉด
NestJS์ ๋์ ์์ด, ์์ TypeScript๋ก ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๋ง๋ ๋ค๊ณ ํด๋ณด์.
์๋น์ค๊ฐ ๋์ด๋ ์๋ก ์กฐ๋ฆฝ ์ฝ๋๋ ๋์ด๋๋ค. ์ฌ๊ธฐ์ ์ธ ๊ฐ์ง ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
1. ์์ฑ ์์๋ฅผ ์ง์ ๊ด๋ฆฌํด์ผ ํ๋ค
AuthService๋ UsersService๊ฐ ๋จผ์ ๋ง๋ค์ด์ ธ์ผ ํ๋ค. UsersService๋ ConfigService๊ฐ ๋จผ์ ๋ง๋ค์ด์ ธ์ผ ํ๋ค. ์๋น์ค๊ฐ ๋์ด๋ ์๋ก "๋๊ฐ ๋๊ตฌ๋ณด๋ค ๋จผ์ ๋ง๋ค์ด์ ธ์ผ ํ๋์ง"๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ํ์
ํด์ผ ํ๋ค. ์์ ํ๋ ํ๋ฆฌ๋ฉด ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
NestJS DI๋ ์ด ์์๋ฅผ ์๋์ผ๋ก ํด์ํด์ค๋ค. providers์ ๋ฑ๋ก๋ง ํ๋ฉด ๋๋ค.
2. ๊ฐ์ ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ ์ ์๋ค
์ธ ๊ณณ ๋ค ๊ฐ์ ์ค์ ์ ์ฝ๋๋ฐ, ConfigService๋ฅผ 3๊ฐ๋ ๋ง๋ค ์ด์ ๊ฐ ์๋ค. ํ๋๋ง ๋ง๋ค์ด์ ๋๋ ค์ฐ๋ฉด ๋๋๋ฐ, ์ง์ newํ๋ฉด ํ๋๋ง ๋ง๋ค๊ณ ๊ณต์ ํ๋ ๊ฒ์ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ด๋ฆฌํด์ผ ํ๋ค.
NestJS๊ฐ ํด์ฃผ๋ ๊ฒ
์ง์ newํ๊ณ , ์์ ๋ง์ถ๊ณ , ๊ณต์ ๊ด๋ฆฌํ๋ ๊ฒ์ NestJS๊ฐ ์ ๋ถ ๋์ ํด์ฃผ๋ ๊ฒ. ์ด๊ฒ์ด DI(์์กด์ฑ ์ฃผ์
)๋ค.
๊ทธ๋ผ ์ด ์์กด์ฑ ์ฃผ์ ์ด ์ ํํ ์ด๋ค ์๋ฆฌ๋ก ๋์ํ๋์ง ์์๋ณด์.
DI๋ ๋ฌด์์ผ๊น ?
์์ ๋ฌธ์ ๋ฅผ ํ ๋ฌธ์ฅ์ผ๋ก ์์ฝํ๋ฉด ์ด๋ ๋ค.
ํ์ํ ๊ฒ์ ์ง์ ๋ง๋ค์ง ๋ง๊ณ , ๋ฐ์์ ๋ฃ์ด์ค.
์ด๊ฒ์ด ์์กด์ฑ ์ฃผ์ (Dependency Injection)์ ์ ๋ถ๋ค.
์ ์ด์ ์ญ์ (IoC)
DI๋ฅผ ์ดํดํ๋ ค๋ฉด, ๋จผ์ IoC(Inversion of Control)๋ผ๋ ์์ ๊ฐ๋ ์ ์์์ผ ํ๋ค.
์ผ๋ฐ์ ์ธ ์ฝ๋์์๋ ๋ด๊ฐ ํ๋ฆ์ ์ ์ดํ๋ค.
IoC์์๋ ํ๋ ์์ํฌ๊ฐ ํ๋ฆ์ ์ ์ดํ๋ค.
๋ ์คํ ๋ ์ฃผ๋ฐฉ์ ๋น์ ํ๋ฉด, ์ ฐํ๊ฐ ๋งค๋ฒ ์์ฅ์ ๊ฐ์ ์ฌ๋ฃ๋ฅผ ์ฌ์ค๋ ๊ฒ ์๋๋ผ, ์์์ฌ ์ ์ฒด๊ฐ ์ฃผ๋ฐฉ์ผ๋ก ๋ฐฐ๋ฌํด์ฃผ๋ ๊ฒ์ด๋ค. ์ ฐํ๋ ์๋ฆฌ์๋ง ์ง์คํ ์ ์๋ค.
DI๋ ์ด IoC๋ฅผ ๊ตฌํํ๋ ๊ตฌ์ฒด์ ์ธ ๋ฐฉ๋ฒ ์ค ํ๋๋ค. "ํ์ํ ์์กด์ฑ์ ์ธ๋ถ์์ ์ฃผ์ ํ๋ค"๋ ๋ป์ด๋ค.
DI์ ์ธ ๊ฐ์ง ๊ตฌ์ฑ์์
| ๊ตฌ์ฑ์์ | ์ญํ | NestJS์์ |
|---|---|---|
| Provider | ์ฃผ์ ๋ ์ ์๋ ๊ฒ | @Injectable() ํด๋์ค |
| Consumer | ์ฃผ์ ๋ฐ๋ ๊ฒ | Controller, ๋ค๋ฅธ Service ๋ฑ |
| Container | ๋์ ์ฐ๊ฒฐํด์ฃผ๋ ๊ฒ | NestJS IoC ์ปจํ ์ด๋ |
์ด ์ธ ๊ฐ์ง๊ฐ ์ด๋ป๊ฒ ๋ง๋ฌผ๋ฆฌ๋์ง, NestJS์ ์ฝ๋๋ฅผ ์ดํด๋ณด์.
NestJS๋ DI๋ฅผ ์ด๋ป๊ฒ ๊ตฌํํ๋๊ฐ
Step 1: @Injectable()
@Injectable()์ TypeScript์ ๋ฐ์ฝ๋ ์ดํฐ(Decorator)๋ค. ์ด ๋ฐ์ฝ๋ ์ดํฐ๊ฐ ๋ถ์ผ๋ฉด, NestJS์๊ฒ **"์ด ํด๋์ค๋ ์์กด์ฑ์ผ๋ก ๊ด๋ฆฌํด์ค"**๋ผ๊ณ ์๋ฆฌ๋ ๊ฒ์ด๋ค.
๋ด๋ถ์ ์ผ๋ก๋ reflect-metadata ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ํด๋์ค์ constructor ํ๋ผ๋ฏธํฐ ํ์
์ ๋ณด๋ฅผ ๋ฉํ๋ฐ์ดํฐ๋ก ์ ์ฅํ๋ค. NestJS๋ ๋์ค์ ์ด ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์, ์ด๋ค ์์กด์ฑ์ด ํ์ํ์ง ํ์
ํ๋ค.
Step 2: @Module()
providers ๋ฐฐ์ด์ ๋ฑ๋ก๋ ํด๋์ค๋ค์ด ์ด ๋ชจ๋์ IoC ์ปจํ
์ด๋์ ๋ฑ๋ก๋๋ค. NestJS๋ ์ฑ์ด ์์๋ ๋ ๋ชจ๋ ๋ชจ๋์ ์ํํ๋ฉด์, ๋ฑ๋ก๋ provider๋ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ค.
Step 3: Constructor Injection
Controller์ constructor์ BoardsService ํ์
์ ์ ์ธํ๋ฉด, NestJS๊ฐ ์๋์ผ๋ก ํด๋น ์ธ์คํด์ค๋ฅผ ์ฐพ์์ ์ฃผ์
ํ๋ค.
์ด ๊ณผ์ ์ ํ์ด๋ณด๋ฉด:
๊ทธ๋์ ์ฐ๋ฆฌ๋ new๋ฅผ ํ ๋ฒ๋ ์ฐ์ง ์๊ณ ๋ boardsService๋ฅผ ์ฌ์ฉํ ์ ์์๋ ๊ฒ์ด๋ค.
์์กด์ฑ ํด์ ๊ณผ์ ์๊ฐํ
๋ง์ฝ BoardsService๊ฐ ๋ค๋ฅธ ์๋น์ค์ ์์กดํ๋ค๋ฉด?
NestJS๋ **์์กด์ฑ ๊ทธ๋ํ๋ฅผ ๋ง๋ค์ด์, ๊ฐ์ฅ ์๋๋ถํฐ ์์๋๋ก ์์ฑํ๋ค.

์ง์ newํ ๋ ์ฐ๋ฆฌ๊ฐ ์๋์ผ๋ก ํ๋ ์ผ์, NestJS ์ปจํ
์ด๋๊ฐ ์๋์ผ๋ก ํด์ฃผ๋ ๊ฒ์ด๋ค.
๊ธฐ๋ณธ DI ์ธ์ ์์์ผ ํ ๊ฒ๋ค
๊ธฐ๋ณธ DI ํจํด์ผ๋ก ๋๋ถ๋ถ์ ์ํฉ์ ํด๊ฒฐํ ์ ์์ง๋ง, ๋ ๋ณต์กํ ์๋๋ฆฌ์ค๋ค๋ ์๋ค.
Custom Provider โ ๊ตฌํ์ฒด๋ฅผ ๊ต์ฒดํด์ผ ํ ๋
๊ฐ์ ํ ํฐ(MAIL_SERVICE)์ผ๋ก ์์ฒญํ์ง๋ง, ํ๊ฒฝ์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ตฌํ์ฒด๋ฅผ ๋ฃ์ ์ ์๋ค. ํ๋ก๋์
์์๋ AWS SES๋ก, ๊ฐ๋ฐ ํ๊ฒฝ์์๋ ์ฝ์์ ์ถ๋ ฅํ๋ Mock์ผ๋ก ๋ฐ๋๋ค.
๋๋ ์ค์ ๊ฐ์ฒ๋ผ ์ด๋ฏธ ๋ง๋ค์ด์ง ๊ฐ์ ์ฃผ์ ํ ์๋ ์๋ค.
๋๋ ํฉํ ๋ฆฌ ํจ์๋ก ๋์ ์์ฑ์ด ํ์ํ ๊ฒฝ์ฐ:
ํฉํ ๋ฆฌ ์์์ ๋น๋๊ธฐ ์ด๊ธฐํ, ์กฐ๊ฑด๋ถ ๋ก์ง, ๋ค๋ฅธ Provider๋ฅผ ์กฐํฉ์ ํ ์ ์๋ค.
Scope โ ์ธ์ ์๋ก์ด ์ธ์คํด์ค๊ฐ ํ์ํ ๊น
๊ธฐ๋ณธ์ ์ผ๋ก NestJS์ Provider๋ ์ฑ๊ธํค์ด๋ค. ํ ๋ฒ ๋ง๋ค๊ณ ์ฑ์ด ์ข ๋ฃ๋ ๋๊น์ง ๊ฐ์ ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ๋ค.
| Scope | ์ฌ์ฉ ์ฌ๋ก |
|---|---|
DEFAULT | ๋๋ถ๋ถ์ ์๋น์ค |
REQUEST | ์์ฒญ๋ณ ์ฌ์ฉ์ ์ปจํ ์คํธ, ๋ฉํฐํ ๋์ |
TRANSIENT | ๊ฐ์ ๋ ๋ฆฝ๋ ์ํ๊ฐ ํ์ํ ๋ก๊ฑฐ |
์ฑ๊ธํค์ด ๊ธฐ๋ณธ์ธ ์ด์ ๋ ์ฑ๋ฅ์ด๋ค. ํ ๋ฒ ๋ง๋ ์ธ์คํด์ค๋ฅผ ๊ณ์ ์ฐ๋ ๊ฒ ๋ ํจ์จ์ ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ๊ผญ ํ์ํ ๋๋ง REQUEST๋ TRANSIENT๋ฅผ ์ฌ์ฉํด์ผํ๋ค.
ํ ์คํธ์์ ๋น๋๋ DI
DI์ ๊ฐ์ฅ ์ค์ฉ์ ์ธ ์ด์ ์ ํ ์คํธ์์ ๋์จ๋ค.
DI ์์ด ํ ์คํธ
๋คํธ์ํฌ๊ฐ ๋๋ฆฌ๋ฉด ํ ์คํธ๊ฐ ๋๋ ค์ง๊ณ , DB๊ฐ ๊บผ์ ธ์์ผ๋ฉด ํ ์คํธ๊ฐ ์คํจํ๋ ๋ฑ ์ธ๋ถ ์ํฅ์ ๋ง์ด ๋ฐ๊ฒ ๋๋ค.
DI๋ก ํ ์คํธ
Test.createTestingModule()์ ์ค์ NestJS ๋ชจ๋๊ณผ ๋์ผํ DI ์ปจํ
์ด๋๋ฅผ ๋ง๋ค๋, ์ํ๋ Provider๋ง mock์ผ๋ก ๊ต์ฒดํ ์ ์๊ฒ ํด์ค๋ค. ์ด๊ฒ์ด ๊ฐ๋ฅํ ์ด์ ๋, Service๊ฐ BoardsRepository๋ฅผ ์ง์ newํ์ง ์๊ณ ์ฃผ์
๋ฐ๊ธฐ ๋๋ฌธ์ด๋ค.
"๋ฐ์์ ๋ฃ์ด๋ฌ๋ผ"๋ DI์ ์์น ๋๋ถ์, ์ฃผ์ ํ๋ ๊ฒ๋ง ๋ฐ๊พธ๋ฉด ์ฝ๋ ํ ์ค ์ ๊ณ ์น๊ณ ํ๊ฒฝ์ ์ ํํ ์ ์๋ค.
๋ง๋ฌด๋ฆฌ
nestjs์ DI๋ ์๋์ ๊ฐ์ ๋ช ํํ ๊ณผ์ ์ด ์์๋ค.
@Injectable()์ด ๋ฉํ๋ฐ์ดํฐ๋ก ํ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ@Module()์providers๊ฐ ์ปจํ ์ด๋์ ํด๋์ค๋ฅผ ๋ฑ๋กํ๊ณ- ์ปจํ ์ด๋๊ฐ ์์กด์ฑ ๊ทธ๋ํ๋ฅผ ๋ง๋ค์ด ์๋๋ถํฐ ์์๋๋ก ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ
- constructor ํ๋ผ๋ฏธํฐ์ ๋ง๋ ์ธ์คํด์ค๋ฅผ ์ฐพ์์ ์ฃผ์ ํ๋
๊ฒฐ๊ตญ DI์ ๋ณธ์ง์ ๊ฐ๋จํ๋ค. "ํ์ํ ๊ฒ์ ์ง์ ๋ง๋ค์ง ๋ง๊ณ , ๋ฐ์์ ๋ฃ์ด์ค" ์ด ํ ๋ฌธ์ฅ์ ์ฝ๋๋ก ๊ตฌํํ ๊ฒ์ด @Injectable()์ด๊ณ , ์์คํ
์ผ๋ก ๊ตฌํํ ๊ฒ์ด IoC ์ปจํ
์ด๋๋ค.
๊ฐ๋จํ๊ฒ @Injectable()ํ๋๋ง์ผ๋ก ์ด๋ฃจ์ด์ก๋ ๊ณผ์ ์ ์ ๋ฆฌํด ๋ณผ ์ ์์ด ์๋ฏธ์์๋ ๊ฒ ๊ฐ๋ค ๐