# Injection scopes

## Injection scopes

다른 언어를 사용하는 사람들에게는 Nest에서 거의 모든 것이 들어오는 요청에서 공유되는 것이 어색할 수 있습니다. 우리는 데이터베이스에 대한 연결 풀, 전역 상태등의 싱글 톤 서비스를 가지고 있습니다. 일반적으로 Node.js는 모든 요청이 별도의 스레드에 의해 처리되는 요청/응답 다중 스레드 상태 비 저장 모델을 따르지 않습니다. 따라서 싱글 톤 인스턴스를 사용하는 것은 애플리케이션에 **안전**합니다.

그러나 컨트롤러의 요청 기반 수명이 의도적인 동작 (예: GraphQL 애플리케이션의 요청별 캐시, 요청 추적 또는 다중 테넌시) 일 수 있는 경우가 있습니다. 어떻게 처리 할 수 있습니까?

## Scopes

기본적으로 모든 공급자는 싱글 톤으로 작동하고 요청 범위를 설정하며 임시 모드로 전환 할 수 있습니다. 차이점을 이해하려면 다음 표를 참조하십시오.

| `SINGLETON` | 각 공급자는 여러 클래스에서 **공유**할 수 있습니다. 공급자 수명은 응용 프로그램 수명주기와 밀접한 관련이 있습니다. 응용 프로그램이 부트 스트랩되면 모든 공급자가 이미 인스턴스화됩니다. 싱글 톤 범위가 기본적으로 사용됩니다. |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `REQUEST`   | 요청 처리가 완료된 후 수신되는 모든 **요청**및 가비지에 대해 제공자의 새 인스턴스가 독점적으로 작성됩니다.                                                                   |
| `TRANSIENT` | 일시적인 제공자는 제공자간에 공유 할 수 없습니다. 다른 공급자가 Nest 컨테이너에 특정 임시 공급자를 요청할 때마다 컨테이너는 새로운 전용 인스턴스를 만듭니다.                                      |

> info **힌트** 싱글 톤 스코프를 사용하는 것이 항상 **권장되는** 방법입니다. 요청간에 공급자를 공유하면 메모리 소비가 줄어들어 애플리케이션 성능이 향상됩니다 (매번 클래스를 인스턴스화하지 않아도 됨).

## Usage

다른 주입 범위로 전환하려면`@Injectable()`데코레이터에 인수를 전달해야 합니다.

```typescript
import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

[custom provider](https://app.gitbook.com/fundamentals/custom-providers)의 경우 추가`scope` 속성을 설정해야합니다.

```typescript
{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

컨트롤러에 관해서는 `ControllerOptions` 객체를 전달하십시오 :

```typescript
@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

> warning **알림** 게이트웨이는 단일 범위 역할을 하므로 요청 범위 공급자에 의존해서는 안됩니다. 하나의 게이트웨이는 내부의 실제 소켓을 캡슐화하며 여러번 인스턴스화 할 수 없습니다.

## Per-request injection

요청 범위의 공급자는 매우 신중하게 사용해야합니다. 스코프는 **인젝션 체인**에서 실제로 버블링됨을 명심하십시오. 컨트롤러가 요청 범위의 공급자에 의존하는 경우 컨트롤러도 실제로 요청 범위입니다.

`CatsController<-CatsService<-CatsRepository` 체인을 상상해 보십시오. `CatsService`가 요청 범위 (및 나머지는 이론적으로 싱글 톤) 인 경우, `CatsController`도 요청 범위가 됩니다 (요청 범위가 지정된 인스턴스는 새로 작성된 컨트롤러에 삽입되어야하기 때문에). 반면에 `CatsRepository`는 싱글 톤으로 남아 있을 것입니다.

> **경고** 이 경우 순환 종속성은 매우 고통스러운 부작용으로 이어질 수 있으므로 부작용을 일으키지 않아야 합니다.

## Request provider

HTTP 애플리케이션에서 요청 범위 제공자를 사용하면 원래 요청 참조를 삽입 할 수 있습니다.

```typescript
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 readonly request: Request) {}
}
```

그러나 이 기능은 마이크로 서비스 또는 GraphQL 응용 프로그램에서는 작동하지 않습니다. [GraphQL](https://app.gitbook.com/graphql/quick-start) 애플리케이션에서 대신 `CONTEXT`를 삽입 할 수 있습니다.

```typescript
import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private readonly context) {}
}
```

그런 다음 `context` 값 (`GraphQLModule`)을 구성하여 `request`를 특성으로 포함할 수 있습니다.

## Performance

요청 범위 공급자를 사용하면 분명히 응용 프로그램 성능에 영향을 미칩니다. Nest가 가능한 한 많은 메타 데이터를 캐시하려고 시도하더라도 각 요청마다 클래스의 인스턴스를 작성해야 합니다. 따라서 평균 응답 시간과 전반적인 벤치마킹 결과가 느려집니다. 공급자가 반드시 요청 범위를 지정할 필요가 없다면 싱글 톤 범위를 고수해야합니다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jakekwak.gitbook.io/nestjs/fundamentals/injection-scopes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
