Архитектура NestJS: модули, провайдеры, DI

↑ 6.2 NestJS · → Следующая

По желанию~3 мин чтенияУровень: junior

Зачем это на собесе

Если в вакансии есть Node.js/NestJS, спросят про модули и DI; знание ASP.NET Core помогает объяснить по аналогии.

Объяснение

NestJS — фреймворк для серверных приложений на TypeScript поверх Express или Fastify. Архитектура вдохновлена Angular и ASP.NET.

ПонятиеРоль
Module (@Module)группирует контроллеры и провайдеры, задаёт границы; imports, providers, controllers, exports
Provider (@Injectable)сервис, репозиторий, фабрика — то, что внедряется
Controller (@Controller)обрабатывает HTTP-запросы
Dependency Injectionвнедрение через конструктор по токену (обычно класс)
ScopeDEFAULT (singleton), REQUEST, TRANSIENT
@Injectable()
export class OrdersService {
  constructor(private readonly repo: OrdersRepository, private readonly config: ConfigService) {}
  find(id: string) { return this.repo.findById(id); }
}
 
@Module({
  imports: [ConfigModule],
  controllers: [OrdersController],
  providers: [OrdersService, OrdersRepository],
  exports: [OrdersService],          // доступен другим модулям
})
export class OrdersModule {}

Кастомные провайдеры: useClass, useValue, useFactory (асинхронная фабрика), useExisting; токены-строки/символы с @Inject('TOKEN'). Динамические модули (forRoot, forRootAsync) настраиваются при импорте.

Нюансы и подводные камни

  • Провайдер, не экспортированный из модуля, недоступен снаружи.
  • Циклические зависимости лечатся forwardRef, но чаще указывают на плохую декомпозицию.
  • REQUEST-scope распространяется вверх по цепочке зависимостей и замедляет приложение.
  • Декораторы работают через reflect-metadata и требуют emitDecoratorMetadata.
  • Не создавайте экземпляры вручную (new Service()): теряется DI.

Практика

  1. Создайте модуль заказов с сервисом и репозиторием.
  2. Подключите провайдер через useFactory с асинхронной инициализацией.
  3. Напишите динамический модуль с forRoot.

Вопросы с ответами

Связанные темы