NestJS의 Providers
기본 개념
- Provider는 다양한 기본 Nest 클래스(서비스, 레포지토리, 팩토리, 헬퍼 등)가 될 수 있습니다.
- Provider는 객체들이 서로 다양한 관계를 맺을 수 있게 하며, Nest 런타임 시스템에 의해 대부분의 "연결 작업"이 처리됩니다.
서비스 생성
이제 서비스를 만드니 컨트롤러도 정리해봅시다. github에 가보시면 정리되어 있는 controller를 볼 수 있습니다.
typescript
import { Injectable } from "@nestjs/common";
import { CatsDto, CreateCatDto, UpdateCatDto } from "./dto/cats.dto";
@Injectable()
export class CatsService {
private readonly cats: CatsDto[] = [];
create(cat: CreateCatDto): CatsDto {
const total = this.cats.length;
const cats = new CatsDto({ id: total + 1, ...cat });
this.cats.push(cats);
return cats;
}
createMany(cats: CreateCatDto[]): CatsDto[] {
const returnCats: CatsDto[] = [];
for (const cat of cats) {
const total = this.cats.length;
const newCat = new CatsDto({ id: total + 1, ...cat });
returnCats.push(newCat);
}
this.cats.push(...returnCats);
return returnCats;
}
findAll(): CatsDto[] {
return this.cats;
}
findOne(id: number): CatsDto {
return this.cats.find((cat) => cat.id === id);
}
update(id: number, cat: UpdateCatDto): CatsDto {
const index = this.cats.findIndex((cat) => cat.id === id);
this.cats[index] = new CatsDto(Object.assign(this.cats[index], cat));
return this.cats[index];
}
remove(id: number): CatsDto {
const index = this.cats.findIndex((cat) => cat.id === id);
const cat = this.cats[index];
this.cats.splice(index, 1);
return cat;
}
}- 위의 예시는
CatsService를 나타냅니다. 이는 데이터 저장 및 검색을 담당하는 간단한 클래스입니다. @Injectable()데코레이터는 Nest의 IoC(제어의 역전) 컨테이너가 이 클래스를 관리할 수 있음을 선언합니다.
Dependency injection
- Nest는 의존성 주입 패턴을 기반으로 구축되었습니다.
- TypeScript를 사용함으로써, 의존성은 타입에 의해 자동으로 해결됩니다.
typescript
constructor(private readonly catsService: CatsService) {}Scopes
- 공급자는 일반적으로 애플리케이션 생명주기와 동기화된 수명("scope")을 가집니다.
- 애플리케이션이 시작될 때 모든 의존성이 해결되어야 하며, 따라서 모든 공급자가 인스턴스화되어야 합니다.
- NestJs Scopes
Custom Providers
- Nest는 공급자 간의 관계를 해결하는 내장 IoC 컨테이너를 가지고 있습니다.
- 공급자를 정의하는 몇 가지 방법이 있으며, 평범한 값, 클래스 및 비동기 또는 동기 팩토리를 사용할 수 있습니다.
- NestJs Custom Provider
Optional Providers
- 데코레이터는 의존성 주입 시 해당 서비스가 반드시 필요하지 않은 경우에 사용됩니다. 이는 모듈에서 해당 서비스를 제공하지 않고, 해당 서비스를 주입할 수 없는 상황에서 사용될 수 있습니다.
@Optional()데코레이터를 사용해 의존성이 선택적임을 나타냅니다.
typescript
import { Injectable, Optional, Inject } from "@nestjs/common";
@Injectable()
export class HttpService<T> {
constructor(@Optional() @Inject("HTTP_OPTIONS") private httpClient: T) {}
}Property-based Injection
- 생성자를 통해 주입되는 것을 생성자 기반 주입이라고 합니다. 특정 상황에서는 속성 기반 주입이 유용할 수 있습니다.
- 속성에
@Inject()데코레이터를 사용하여 의존성을 주입할 수 있습니다.
typescript
import { Injectable, Inject } from "@nestjs/common";
@Injectable()
export class HttpService<T> {
@Inject("HTTP_OPTIONS")
private readonly httpClient: T;
}provider Registration
- 공급자(CatsService)와 해당 서비스의 소비자(CatsController)를 정의한 후, Nest가 주입을 수행할 수 있도록 모듈 파일에 서비스를 등록해야 합니다.
typescript
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 {}