Vložení služby Nest.js z jiného modulu

Používání služeb z jiného modulu v Nest.js vyžaduje specifické kroky, aby bylo zajištěno správné fungování závislostí a celková struktura modulu. Na příkladu dvou modelových modulů si ukážeme, jak se exportují a importují služby.

Vytvoření projektu Nest.js

Pro vygenerování nového projektu v Nest.js je nezbytné mít nainstalované CLI (Command Line Interface). Pokud jej nemáte, nainstalujte ho pomocí tohoto příkazu:

 npm install -g @nestjs/cli

Po úspěšné instalaci CLI, vytvořte nový projekt Nest.js příkazem:

 nest new <nazev-projektu>

Místo „“ zadejte vámi zvolený název projektu. Tento příkaz vytvoří nový projekt s určeným jménem.

Struktura vygenerovaného projektu by měla odpovídat obrázku, který následuje:

Pro demonstraci vkládání služby mezi moduly vytvoříme dva moduly: `module-a` a `module-b`. Spolu s nimi vygenerujeme i odpovídající soubory pro služby a kontrolery.

Modul `module-a` vygenerujete tímto příkazem:

 nest generate module module-a

A pro vytvoření modulu `module-b` použijte tento příkaz:

 nest generate module module-b

Nyní vytvoříme soubory služeb a kontrolerů pro modul `module-a` pomocí:

 nest generate service module-a && nest generate controller module-a

A stejným způsobem i pro modul `module-b`:

 nest generate service module-b && nest generate controller module-b

Po těchto krocích by měl váš projekt obsahovat složky `src/module-a` a `src/module-b`, jak je znázorněno níže:

Exportování služby z modulu A

Pro export služby z `module-a`, musíme tuto službu uvést v poli `exports` v modulu `module-a.module.ts`. Standardně Nest.js CLI toto pole při generování modulu nevytváří, takže výchozí soubor vypadá takto:

 
import { Module } from '@nestjs/common';
import { ModuleAService } from './module-a.service';
import { ModuleAController } from './module-a.controller';

@Module({
  providers: [ModuleAService],
  controllers: [ModuleAController],
})

export class ModuleAModule {}

Abychom zpřístupnili službu `module-a.service.ts` modulům, které importují `module-a`, přidáme pole `exports` do dekorátoru `@Module` a vložíme do něj `ModuleAService`.

Zde je příklad:

 import { Module } from '@nestjs/common';
import { ModuleAService } from './module-a.service';
import { ModuleAController } from './module-a.controller';

@Module({
  providers: [ModuleAService],
  controllers: [ModuleAController],
  exports: [ModuleAService],
})

export class ModuleAModule {}

Pro demonstrační účely přidáme do souboru `module-a.service.ts` jednoduchou funkci:

 import { Injectable } from '@nestjs/common';

@Injectable()
export class ModuleAService {
  getHello(): string {
    return 'Ahoj z modulu A!';
  }
}

Tato funkce vrací jednoduchý textový řetězec. Pro ověření správného importu a vkládání služeb tuto funkci zavoláme z modulu `module-b` po vložení služby `module-a`.

Import služby do modulu B

Aby bylo možné importovat modul do jiného modulu, musíte jej uvést v poli `imports` cílového modulu. V našem případě musíme `module-a` přidat do pole `imports` v dekorátoru `@Module` modulu `module-b`.

Stejně jako předtím, Nest.js CLI automaticky negeneruje pole `imports`, takže jej musíme přidat ručně.

Nejprve importujte `module-a.module.ts` do `module-b.module.ts`, vytvořte pole `imports` a vložte do něj `ModuleAModule`:

 
import { Module } from '@nestjs/common';
import { ModuleBController } from './module-b.controller';
import { ModuleBService } from './module-b.service';
import { ModuleAModule } from '../module-a/module-a.module';

@Module({
  imports: [ModuleAModule],
  controllers: [ModuleBController],
  providers: [ModuleBService],
})

export class ModuleBModule {}

Nyní otevřete soubor `module-b.service.ts` a importujte dekorátor `Inject` a `ModuleAService` z `@nestjs/common` a `../module-a/module-a.service`, v tomto pořadí:

 import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from '../module-a/module-a.service';

Dekorátor `Inject` označuje parametr jako cíl pro vkládání závislostí.

Do třídy `ModuleBService` přidejte následující blok kódu:

 @Inject(ModuleAService)
  private readonly moduleAService: ModuleAService;

Tento kód umožňuje `ModuleBService` přístup k metodám, které nabízí `ModuleAService`.

Pro otestování služby můžeme zavolat metodu `getHello` modulu `ModuleAService`:

 
import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from 'src/module-a/module-a.service';

@Injectable()
export class ModuleBService {
  @Inject(ModuleAService)
  private readonly moduleAService: ModuleAService;

  getHello(): string {
    return this.moduleAService.getHello();
  }
}

Nakonec otevřete soubor `module-b.controller.ts` a nahraďte jeho obsah následujícím kódem:

 
import { Controller, Get } from '@nestjs/common';
import { ModuleBService } from './module-b.service';

@Controller('module-b')
export class ModuleBController {
  constructor(private readonly moduleBService: ModuleBService) {}

  @Get('/hello')
  getHello(): string {
    return this.moduleBService.getHello();
  }
}

Tento kód nastavuje obslužnou rutinu pro GET požadavek na funkci `getHello`.

Nyní můžete provést GET požadavek pomocí curl na `localhost:3000/module-b/hello`. Konzole by měla vypsat zprávu „Ahoj z modulu A!“.

Tímto jste úspěšně vložili službu do jiného modulu. To je užitečné při vývoji API v Nest.js, které obsahují více modulů, které mezi sebou potřebují volat své metody.

Výhody vkládání mezi moduly

I když se zdá přímé volání služby z jiného modulu jednodušší, v dlouhodobém horizontu by to vedlo ke komplikovanějšímu, méně udržovatelnému a hůře škálovatelnému systému.

Naproti tomu vkládání mezi moduly podporuje modularitu kódu a jeho znovupoužitelnost, což usnadňuje jeho údržbu. Centralizuje také závislosti, zlepšuje testovatelnost a podporuje škálovatelnou architekturu.