Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке Singleton-провайдери?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Singleton-провайдер - це провайдер, у якого існує лише один екземпляр на весь застосунок NestJS: контейнер кешує екземпляр при першому створенні, і всі наступні запити до цього провайдера отримують ту саму копію. **Ключове:** усі провайдери NestJS мають `scope: DEFAULT` за замовчуванням, а `DEFAULT` = singleton; для стану, залежного від конкретного запиту, натомість використовують `Scope.REQUEST` чи `Scope.TRANSIENT`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке Singleton-провайдер **Singleton-провайдер** - це **провайдер, у якого існує лише один екземпляр (instance)** на весь застосунок NestJS. Коли контейнер NestJS вперше створює цей провайдер, він **кешує екземпляр**, і всі наступні запити до цього провайдера отримують **ту саму копію**. ## Приклад ```javascript import { Injectable } from '@nestjs/common'; @Injectable() export class CounterService { private counter = 0; increment() { this.counter++; return this.counter; } } ``` І два контролери використовують цей сервіс: ```javascript import { Controller, Get } from '@nestjs/common'; import { CounterService } from './counter.service'; @Controller('a') export class AController { constructor(private readonly counterService: CounterService) {} @Get() add() { return this.counterService.increment(); } } @Controller('b') export class BController { constructor(private readonly counterService: CounterService) {} @Get() add() { return this.counterService.increment(); } } ``` ### Що відбудеться: - NestJS створить **один спільний екземпляр** `CounterService`; - обидва контролери (`AController` і `BController`) використовуватимуть **той самий об'єкт**; - значення лічильника буде **спільним**: | Запит | Результат | |---|---| | `GET /a` → `1` | створюється вперше | | `GET /b` → `2` | використовує той самий екземпляр | ## Чому це зручно - **Економія ресурсів:** об'єкт створюється лише один раз. - **Спільний state:** зручно, якщо потрібно кешувати дані, тримати пул підключень тощо. - **Простота:** не потрібно вручну керувати часом життя об'єкта. ## Як NestJS вирішує, що провайдер - Singleton За замовчуванням **усі провайдери в NestJS мають** `scope: DEFAULT`, а `DEFAULT` = **singleton**. ```javascript @Injectable({ scope: Scope.DEFAULT }) // те саме, що просто @Injectable() export class MyService {} ``` ## Інші типи областей видимості (Scope) | Scope | Опис | |---|---| | Singleton (DEFAULT) | Один екземпляр на весь застосунок (за замовчуванням) | | Request | Новий екземпляр на кожен HTTP-запит | | Transient | Новий екземпляр при кожному впровадженні (щоразу новий об'єкт) | ### Приклад Request-Scoped провайдера: ```javascript import { Injectable, Scope } from '@nestjs/common'; @Injectable({ scope: Scope.REQUEST }) export class RequestService { constructor() { console.log('Новий екземпляр для запиту!'); } } ``` У цьому випадку при кожному HTTP-запиті Nest створюватиме **новий об'єкт**, а не використовуватиме спільний. ## Коли Singleton-провайдер - це добре Чудово підходить для: - сервісів зі **спільною логікою**, не залежною від запиту; - **логування**, **конфігурації**, **роботи з БД** (одне підключення); - кешування, токенів, сервісів, які не зберігають унікальні дані запиту. ## Коли Singleton-провайдер - погана ідея Не використовуй Singleton, якщо: - провайдер зберігає **стан, залежний від конкретного запиту**; - він має бути **ізольований** між користувачами; - він містить **дані користувача**, які не можна ділити між запитами. У таких випадках обирають `Scope.REQUEST` чи `Scope.TRANSIENT`. ## Підсумок | Поняття | Опис | |---|---| | Singleton-провайдер | Один спільний екземпляр провайдера на весь застосунок | | Створюється | Один раз при ініціалізації модуля | | Використовується | У всіх місцях, де він впроваджений | | За замовчуванням | Усі провайдери NestJS - singleton | | Переваги | Швидше, економніше, зручно для кешів, констант, БД | | Обмеження | Не підходить для залежностей, унікальних на кожен запит |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.