ํ๋ก๋ฐ์ด๋๋ Nest์ ํต์ฌ ๊ฐ๋ ์ ๋๋ค. ๋ง์ ๊ธฐ๋ณธ Nest ํด๋์ค๋ค์ services, repositories, factories, helpers ๋ฑ์ provider๋ก ์ทจ๊ธ๋ ์ ์์ต๋๋ค.
provider์ ํต์ฌ์ ์์กด์ฑ์ผ๋ก ์ฃผ์ ๋ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.(๊ฐ์ฒด๋ค์ด ์๋ก ์์กดํ๋ฉฐ ๋ค์ํ ๊ด๊ณ๋ฅผ ํ์ฑํจ), ๊ทธ๋ฆฌ๊ณ ๊ฐ์ฒด ์ธ์คํด์ค ๊ฐ์ ๊ด๊ณ๋ฅผ ๋งบ๋ ์์ (์ฐ๊ฒฐ)์ Nest ๋ฐํ์ ์์คํ ์ ์์ํฉ๋๋ค.
์ปจํธ๋กค๋ฌ๋ HTTP ์์ฒญ์ ๋ฐ๊ณ ๋ณต์กํ ํต์ฌ ๋ก์ง๋ค์ ํ๋ก๋ฐ์ด๋ฉ๊ฒ ์์ํ๋ ์ผ์ ์ ๋ดํฉ๋๋ค.
ํ๋ก๋ฐ์ด๋๋ ์์ ์๋ฐ์คํฌ๋ฆฝํธ ํด๋์ค๋ก module์ provider
๋ก ์ ์ธ๋์ด ์์ต๋๋ค.
Nest๋ ๊ฐ์ฒด ์งํฅ์ ์ธ ๋ฐฉ์์ผ๋ก ์์กด์ฑ์ ์ค๊ณํ๊ณ ๊ตฌ์ฑํ ์ ์๊ฒ ํด์ฃผ๊ธฐ ๋๋ฌธ์ SOLID ์์น์ ๋ฐ๋ฅด๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
$ nest g service <service class name>
์์ ๊ฐ์ nest cli ๋ช ๋ น์ด๋ก ๊ฐ๋จํ๊ฒ service๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
// cats.service.ts
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
์์ CatsService
ํ๋์ ํ๋กํผํฐ์ ๋ ๊ฐ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง ๊ฐ๋จํ ํด๋์ค์
๋๋ค.
@Injectable()
๋ฐ์ฝ๋ ์ดํฐ๋ CatsService
๊ฐ Nest IoC ์ปจํ
์ด๋์ ์ํด ๊ด๋ฆฌ๋๋ ํด๋์ค๋ผ๋ ์ ๋ณด๋ฅผ ์ฒจ๋ถํ๋ ์ญํ ์ ํฉ๋๋ค.
// interfaces/cat.interface.ts
export interface Cat {
name: string;
age: number;
breed: string;
}
์๋ Cat
์ธํฐํ์ด์ค ์
๋๋ค.
// cats.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
์ ๊ณ ์์ด ์ ๋ณด๋ฅผ ๊ฒ์ํ๋ CatsService
์ Cat
์ธํฐํ์ด์ค๋ ์์ฑํ์ผ๋ ์ด์ CatsService
๋ฅผ CatsController
๋ด๋ถ์์ ์ฌ์ฉํ๋ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ CatsController
์์ CatsService
๋ ํด๋์ค ์์ฑ์๋ฅผ ํตํด ์ฃผ์
๋์์ต๋๋ค.
์์ฒ๋ผ private
๋จ์ถ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ฉด ์ ์ธ๊ณผ ์ด๊ธฐํ๋ฅผ ๋์์ ํ ์ ์์ต๋๋ค. TS ๋ฌธ๋ฒ์ ํ์ธํ์ธ์
Nest๋ DI๋ก ์๋ ค์ง ๊ฐ๋ ฅํ ๋์์ธ ํจํด์ ๋ฐํ์ผ๋ก ๊ตฌ์ถ๋์์ต๋๋ค.
constructor(private catsService: CatsService) {}
catsService
๋ ์์ฑ๋์ด ๋ฐํ๋ CatsService
์ ์ธ์คํด์ค๋ฅผ ํ ๋น๋ฐ์ต๋๋ค.(์ผ๋ฐ์ ์ธ ์ฑ๊ธํค์ ๊ฒฝ์ฐ์๋ ์ด๋ฏธ ๋ง๋ค์ด์ง ๊ธฐ์กด ์ธ์คํด์ค๋ฅผ ํ ๋น๋ฐ์ต๋๋ค.)
ํ๋ก๋ฐ์ด๋๋ ์ผ๋ฐ์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์๋ช ์ฃผ๊ธฐ์ ๋๊ธฐํ๋ scope(๋ผ์ดํํ์)์ ๊ฐ์ง๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ถํธ์คํธ๋ฉ ๋ ๋ ๋ชจ๋ ์์กด์ฑ์ด ํด๊ฒฐ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ํ๋ก๋ฐ์ด๋๋ค์ ์ธ์คํด์คํ๋์ด์ผ ํฉ๋๋ค.
๋์ผํ๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ข ๋ฃ๋ ๋ ๋ชจ๋ ํ๋ก๋ฐ์ด๋๋ค ๋ํ ์ญ์ ๋ฉ๋๋ค.
ํ๋ก๋ฐ์ด๋์ ๋ผ์ดํํ์์ request-sceoped๋ก ๋ง๋ค ์๋ ์์ต๋๋ค. injection scopes
Nest๋ ๋นํธ์ธ IoC ์ปจํ ์ด๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. IoC ์ปจํ ์ด๋๋ ์์กด์ฑ ์ฃผ์ ๊ธฐ๋ฅ์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ก๋ฐ์ด๋ ๊ฐ์ ๊ด๊ณ, ์์กด์ฑ์ ํด๊ฒฐํฉ๋๋ค.
ํ๋ก๋ฐ์ด๋๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ต๋๋ค, ๋จ์ ๊ฐ, ํด๋์ค, ๋น๋๊ธฐ ๋๋ ๋๊ธฐ ํฉํ ๋ฆฌ๋ค์ ํ๋ก๋ฐ์ด๋๋ก ์ ์ํ ์ ์์ต๋๋ค.
๋ฐ๋์ ์์กด์ฑ ์ฃผ์
์ด ํ์ํ์ง ์์ ๊ฒฝ์ฐ์๋ ์์ฑ์ ์๊ทธ๋์ฒ์ @Optional
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ์ ํ๋ก๋ฐ์ด๋์์ ๋ช
์ํ ์ ์์ต๋๋ค.
ํด๋์ค๊ฐ ๊ตฌ์ฑ ๊ฐ์ฒด์ ์์กดํ ์ ์์ง๋ง, ์ ๋ฌ๋์ง ์๋๋ค๋ฉด ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํ๋๋ก ํด์ผํฉ๋๋ค. ํ๋ก๋ฐ์ด๋์ ๋ถ์ฌ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์๊ฒ ํ๊ธฐ ์ํจ์ ๋๋ค.
import { Injectable, Optional, Inject } from '@nestjs/common';
@Injectable()
export class HttpService<T> {
constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
์์ ์์์๋ ์ฌ์ฉ์ ์ ์ ํ๋ก๋ฐ์ด๋๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ์ด ๋๋ฌธ์ HTTP_OPTIONS ์ฌ์ฉ์ ์ ์ ํ ํฐ์ ํฌํจํ๊ณ ์์ต๋๋ค.
์ด์ ์์ ๋ค์ ์์ฑ์ ๊ธฐ๋ฐ ์ฃผ์ ์ ๋ณด์ฌ์ฃผ์๋๋ฐ, ์ด๋ ์์ฑ์ ์์์ ํด๋์ค๋ฅผ ํตํด ์์กด์ฑ์ ๋ํ๋ด๋ ๊ฒ์ ๋๋ค.
์ฌ์ฉ์ ์ ์ ํ๋ก๋ฐ์ด๋์ ๊ทธ๋ค๊ณผ ๊ด๋ จ๋ ํ ํฐ์ ๋ํด ๋ ์์ธํ ์ ๋ณด๋ ๋ค์์ ์ฐธ์กฐํ์ธ์
์ง๊ธ๊น์ง ์ดํด๋ณธ ์์กด์ฑ ์ฃผ์ ์ ์์ฑ์ ๊ธฐ๋ฐ ์ฃผ์ (constructor-based injection)์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ํ๋ก๋ฐ์ด๋๊ฐ ์์ฑ์ ๋ฉ์๋๋ฅผ ํตํด ์ฃผ์ ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด๋ค ๊ฒฝ์ฐ์๋ ์์ฑ ๊ธฐ๋ฐ ์ฃผ์ (property-based injection)์ด ์ ์ฉํฉ๋๋ค. ์ต์์ ํด๋์ค๊ฐ ํ๋ ์ด์์ ํ๋ก๋ฐ์ด๋์ ์์กดํ๋ ๊ฒฝ์ฐ,
ํ์ ํด๋์ค์์ super()
๋ฅผ ํธ์ถํด์ ๋ชจ๋ ์์กด์ฑ๋ค์ ์ ๋ฌํ๋ ๊ฒ์ ๋ฒ๊ฑฐ๋ก์ด ์ผ์
๋๋ค. ์ด๋ฌํ ์ผ์ ํผํ๊ธฐ ์ํด์ ์ฌ์ฉํ๋ ๊ฒ์ด ํ๋กํผํฐ ๋ ๋ฒจ์์ @Inject()
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์์กด์ฑ ์ฃผ์
์ ํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
import { Injectable, Inject } from '@nestjs/common';
@Injectable()
export class HttpService<T> {
@Inject('HTTP_OPTIONS')
private readonly httpClient: T;
}
๋ง์ฝ ์๋ฌด ํด๋์ค๋ ํ์ฅํ์ง ์๋๋ค๋ฉด, ์์ฑ์ ๊ธฐ๋ฐ ์ฃผ์ ์ ์ฌ์ฉํ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
// app.module.ts
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 {}
ํ๋ก๋ฐ์ด๋์ธ CatsService
์ ์๋น์ค์ consumer CatsController
๋ฅผ ์ ์ํ์์ผ๋๊น, Nest์ ์๋น์ค๋ฅผ ๋ฑ๋กํ์ฌ ์์กด์ฑ ์ฃผ์
์ด ๊ฐ๋ฅํ๋๋ก ํด์ผํฉ๋๋ค.
๊ทธ๋ฌ๊ธฐ ์ํด์ app.module.ts
๋ฅผ ์์ ๊ฐ์ด ์์ ํ์ฌ @Module
๋ฐ์ฝ๋ ์ดํฐ์ CatsService
๋ฅผ ํ๋ก๋ฐ์ด๋์ ์ถ๊ฐํฉ๋๋ค.
์ด๋ ๊ฒ ํจ์ผ๋ก์จ Nest๋ CatsController
ํด๋์ค์ ์์กด์ฑ์ ํด๊ฒฐํด ์ค ์ ์์ต๋๋ค.
ํน์ ์ํฉ์์๋ ๋ด์ฅ๋ ์์กด์ฑ ์ฃผ์ ์์คํ ์ ๋ฒ์ด๋์ ์๋์ผ๋ก ํ๋ก๋ฐ์ด๋๋ฅผ ๊ฒ์ํ๊ฑฐ๋ ์ธ์คํด์คํ ํด์ผํ ์ ์์ต๋๋ค.
๊ธฐ์กด ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ํ๋ก๋ฐ์ด๋๋ฅผ ๋์ ์ผ๋ก ์ธ์คํด์คํ ํ๋ ค๋ฉด Module ๋ ํผ๋ฐ์ค๋ฅผ ์ฐธ์กฐํ์ธ์. Module reference
bootstrap()
ํจ์ ์์์ ํ๋ก๋ฐ์ด๋๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด์๋ Standalone application ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์ Standalone application