Skip to main content

Що таке глобальні провайдери?

Що таке глобальний провайдер

Глобальний провайдер (global provider) - це провайдер, який доступний у всьому застосунку NestJS, навіть якщо модуль, де він оголошений, не імпортовано явно в інші модулі.

Іншими словами: якщо ти зареєстрував провайдер як глобальний, тобі більше не потрібно вказувати imports: [SomeModule] у кожному модулі - NestJS сам робить цей провайдер доступним усюди.

Приклад без глобального провайдера

javascript
// logger.service.ts @Injectable() export class LoggerService { log(msg: string) { console.log(`[LOG]: ${msg}`); } } // logger.module.ts @Module({ providers: [LoggerService], exports: [LoggerService], }) export class LoggerModule {}

Щоб використати LoggerService в інших модулях, нам доведеться імпортувати LoggerModule вручну в кожному місці:

javascript
@Module({ imports: [LoggerModule], }) export class UsersModule {}

Приклад із глобальним провайдером

Зробимо модуль глобальним, використовуючи декоратор @Global():

javascript
import { Global, Module } from '@nestjs/common'; import { LoggerService } from './logger.service'; @Global() @Module({ providers: [LoggerService], exports: [LoggerService], }) export class LoggerModule {}

Тепер LoggerService доступний у всіх модулях застосунку, навіть якщо LoggerModule ніде не імпортований.

javascript
@Injectable() export class UsersService { constructor(private readonly logger: LoggerService) {} findAll() { this.logger.log('Fetching users...'); return ['John', 'Alex']; } }

NestJS автоматично реєструє LoggerService у глобальному DI-контейнері, тому він доступний у будь-якому місці без додаткових імпортів.

Як це працює всередині

  • Кожен модуль у NestJS має власну область видимості (scope).
  • Коли ти додаєш @Global(), Nest реєструє провайдери модуля в кореневому контейнері.
  • Усі інші модулі "бачать" ці провайдери, навіть не імпортуючи модуль.

Де це корисно

Глобальні провайдери зазвичай використовуються для кросс-застосунковних сервісів, наприклад:

Тип сервісуПриклад
АвторизаціяAuthService, JwtService, AuthGuard
КонфігураціяConfigService з @nestjs/config
ЛогуванняLoggerService
Робота з кешемCacheService, RedisService
Події / сповіщенняEventBus, NotificationService

Важливо: обережно з глобальністю

Хоча це зручно, зловживати глобальними провайдерами не варто.

Мінуси:

  • важко відстежити, звідки приходить залежність;
  • порушується інкапсуляція модулів;
  • можливі конфлікти імен при великій кількості глобальних провайдерів;
  • тестування ускладнюється (mock потрібно підмінювати глобально).

Краще:

  • використовувати глобальні провайдери лише для інфраструктури (логер, конфіг, кеш);
  • а бізнес-логіку лишати модульною.

Альтернатива: глобальна реєстрація без @Global()

Іноді можна зареєструвати глобальний провайдер програмно, наприклад, у main.ts чи через Dynamic Module.

Приклад через app.useGlobalFilters(), app.useGlobalPipes(), app.useGlobalInterceptors()

javascript
const app = await NestFactory.create(AppModule); app.useGlobalFilters(new HttpExceptionFilter()); app.useGlobalPipes(new ValidationPipe()); app.useGlobalInterceptors(new LoggingInterceptor());

Ці елементи теж стають глобальними провайдерами, але на рівні всього застосунку (без декоратора @Global()).

Приклад динамічного глобального модуля

javascript
@Global() @Module({}) export class ConfigModule { static forRoot(envFile: string): DynamicModule { return { module: ConfigModule, providers: [ { provide: 'CONFIG_PATH', useValue: envFile, }, ConfigService, ], exports: [ConfigService], }; } }

Тепер ConfigService глобально доступний усюди.

Підсумок

ПоняттяОпис
Глобальний провайдерПровайдер, доступний у всіх модулях без явного імпорту
Створюється через@Global() над модулем, або useGlobal*() при ініціалізації
Використовується дляЗагальносистемних сервісів: логер, конфіг, автентифікація
ПеревагиСпрощує архітектуру, менше імпортів
НедолікиПриховані залежності, складніше тестувати, ризик конфліктів
РекомендаціяРоби глобальними лише інфраструктурні сервіси, а бізнес-логіку - модульною

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.