NestJS 독학 - Providers

김정원·2020년 11월 15일
0

NestJS 독학

목록 보기
3/4
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

NestJS 구조 안에서 작동하는 기능을 제공하는 핵심적인 부분이다. @Injectable() 데코레이터를 통해 주입할 클래스를 지정하고 해당 클래스 안에서 메소드를 통해 비즈니스 로직을 작성하고 Provider를 통해 각 컨트롤러나 모듈에서 호출할 수 있다.

Nest에서는 모든 클래스가 SOLID 원칙을 지켜야 한다고 설명한다.
SOLID 원칙이란? : 내용보기

Service

cats.service.ts를 생성하여 cats 콘트롤러에서 사용할 비즈니스 로직을 정의해보자.

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;
  }
}

$ nest g service cats CLI 명령을 통해 생성해 줄 수도 있다.

cats Service의 예제에서는 CatsService 클래스를 @Injectable()데코레이터를 이용해 Provider로 사용될 클래스임을 알려준다. 1개의 프로퍼티와 2개의 메소드를 가지고 있다. 먼저 cat프로퍼티의 인터페이스를 정의해 준다.

// interface/cats.interface.ts
export interface Cat {
  name: string;
  age: number;
  bread: string;
}

눈치 챘겠지만, NestJS에서는 파일명에 대한 규칙이 정해져 있다. 꼭 지켜야하는 건 아니지만 규칙을 지켜가면서 설계하는 걸 권장한다.

cat 객체를 조작하는 간단한 비즈니스 로직을 작성했다. 이를 cats.controller.ts에서 사용하려면 아래와 같이 constructorCatsService를 받아와서 사용할 수 있다.

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) {}
	//CatsService를 catsService로 불러온다. (의존성 주입)

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

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

@Injectable() 데코레이터가 붙어있는 클래스는 constructor를 통해서 의존성을 주입할 수 있다. 이렇게 하면 클래스 내부에서 this를 통해서 해당 서비스에 접근할 수 있게된다.

Scopes

Provider들은 보통의 애플리케이션와 라이프타임이 동일하다. 애플리케이션이 실행되면 모든 의존성이 주입되고 Provider들이 인스턴스화 된다. (참고로 NestJS의 모든 인스턴스는 싱글톤으로 생성되기 때문에 모듈간의 자연스러운 동작이 가능하다.) 그리고 애플리케이션이 종료되면 모든 Provider들은 파괴된다.

Custom providers

NestJS는 내장된 IoC 컨테이너를 통해 Provider들의 관계를 정의하고 의존성과 주입을 실행한다. 일반적으로는 @Injectable()을 통해 클래스를 Provider로 정의했지만 그 외에도 다양한 방법으로 일반 값이나 동기/비동기 팩토리를 Provider로 정의할 수도 있다. 사실 일반적으로 아래와 같이 providers로 전달하는 방법은 다양한 방법중에 Class Provider를 전달하는 방법을 약어로 설정한 것이다.

//두 코드는 동일하다

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

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

이 외에도 Optional Provider, Property-based Injection 등등의 기능이 있다. 간략하게만 알아보면 Optinal Provider@Optional()데코레이터를 통해 생성자에서 상위 Provider를 선택적으로 가져올 수 있고, Property-based Injection의 경우에는 Provider의 constructor의 인수에 @Inject()데코레이터를 통해 다른 Provider의 의존성을 주입 받을 수 있는 것이다. 자세한 내용은 여기를 참고

다음은 ControllerProvider를 묶어주는 Module에 대해 알아보자.

profile
영원히 공부중

0개의 댓글