-
5. Provider (NestJs)IT/NodeJs 2020. 10. 28. 15:23
1. Provider란?
- NestJS의 기본 클래스들은 Provider로서 다루어진다.
- Provider는 @Injectable() 데코레이터를 사용한다.
- Provider 의 기본 아이디어는 의존성 주입(Dependancy Injection) 이다. (Java Spring의 Bean DI와 유사)
- 즉 객체는 서로 다양한 의존관계를 가질 수 있으며, Provider의 의존성 기능은 NestJS의 런타임에 의해 관리된다.
2. Service
- Nest에서 컨트롤러는 HTTP 요청을 처리하고 더 복잡한 작업을 Provider 에게 위임한다.
- 복잡한 비즈니스 로직을 처리하는 부분을 Service Layer로 설계한다.
- Service Layer의 객체를 Provider로 정의하고, @Injectable() 데코레이터를 붙여준 후, Controller에 주입시킨다.
CLI를 사용하여 서비스 모듈을 생성할 수 있다. $ nest g service [서비스명]
- Service 객체를 Controller의 생성자를 통해 주입한다.
<cats.controller.ts> import { .... } from ....; import {CatsService} from './cats.service'; //service 모듈 추가 ....... @Controller('cats') export class CatsController { constructor (private catsService: CatsService){} //생성자를 통해 Injection @Post() async create(......) { //do create } }
- 위의 생성자에서, Nest는 catService 객체를 생성하여 주입하며, 일반적인 싱글톤의 경우 이미 만들어진 객체를 주입시켜 준다.
3. Scope (범위)
- Provider는 application lifecycle과 동기화되는 lifetime 을 갖는다.
- 일반적으로 application이 초기화 될 때, 모든 의존성이 연결되어야 하기 때문에, 모든 객체가 생성된다.
- 아래와 같은 옵션을 통해 객체의 Scope 를 변경할 수 있다.
DEFAULT Provider 1개의 객체가 어플리케이션 전역에 공유된다. 객체의 lifetime은 application lifecycle과 같다.
application이 시동되면, singleton providers 객체가 생성된다. singleton scope는 디폴트로 동작한다.REQUEST 각각의 request 마다, 새로운 provider 객체가 만들어진다.request 처리가 끝나면 가비지컬렉팅 된다. TRANSIENT Consumer 간에 공유되지 않는다. 각각의 consumer는 새로운 전용 인스턴스를 받게 된다. *사용방법 import {Injectable, Scope} from '@nestjs/common'; @Injectable({ scope: Scope.REQUEST }) export class CatService {}
4. Controller Scope (컨트롤러 범위)
- 컨트롤러도 모든 리퀘스트 메소드 핸들러에 적용되는 scope를 가질 수 있다.
- Provider scope와 마찬가지로, controller scope도 lifetime 을 갖는다.
- request-scoped controller에서, 새로운 인스턴스는 각 request가 들어올때 생성되며, request가 처리 완료되면 가비지컬렉팅 된다.
*Controller Scope는 scope 프로퍼티로 선언 가능하다. @Controller({ path: 'cats', scope: Scope.REQUEST, }) export class CatsController {}
5. Scope 계층
- CatsController <- CatsService <- CatsRepository 의 관계에서 CatsService가 request-scope 이고, 나머지는 default 라면, CatsController는 service에 의존적이기 때문에 request-scope가 되고, Repository는 의존적이지 않기 때문에 디폴트를 유지한다.
6. Request provider
- HTTP 서버 기반 application 에서, request-scoped provier 를 이용해서 original request 객체에 접근이 가능하다. (injecting REQUEST object)
import { Injectable, Scope, Inject } from '@nestjs/common' import { REQUEST } from '@nestjs/core'; import { Request } from 'express'; @Injectable({ scope: Scope.REQUEST }) export class CatsService { constructor(@Inject(REQUEST) private request: Request) {} }
7. Performance (성능)
- request-scoped provider를 사용하면 Nest는 가능한 많은 메타데이터를 캐시하려고 시도하지만, 각 요청에서 클래스의 인스턴스를 생성해야 한다.
- 이런 이유로, 평균 응답 시간과 전체 벤치마킹 결과가 느려 질 것이다.
- provider가 request-scoped 이어야만 하는 경우가 아니라면, 디폴트 scope 사용을 강력히 권장한다.
'IT > NodeJs' 카테고리의 다른 글
자바스크립트 호출 스택(Call Stack) 동작 예제 (0) 2022.03.18 6. Modules (NestJs) (0) 2020.10.28 4. NestJS 설치 및 실행, 기본구조 (0) 2020.10.28 3. NestJs (0) 2020.10.28 2. Node.js 의 모듈 (0) 2020.10.14