Wstrzykiwanie usługi Nest.js z innego modułu
W Nest.js proces włączania usług z jednego modułu do drugiego wymaga precyzyjnych działań, aby zapewnić właściwe zarządzanie zależnościami i logiczną strukturę modułów. Na przykładzie dwóch modułów przedstawiamy krok po kroku, jak eksportować i importować usługi.
Tworzenie nowego projektu Nest.js
Zanim zaczniesz, upewnij się, że masz zainstalowany Nest.js CLI. Jeśli go nie posiadasz, użyj poniższego polecenia:
npm install -g @nestjs/cli
Po instalacji narzędzia CLI, stwórz nowy projekt Nest.js za pomocą komendy:
nest new <project-name>
Zastąp „<project-name>” wybraną przez ciebie nazwą. To polecenie utworzy nowy projekt Nest.js.
Struktura twojego projektu powinna wyglądać podobnie jak na poniższym obrazku:

Aby przećwiczyć mechanizm wstrzykiwania usługi między modułami, stworzymy dwa moduły – "module-a" i "module-b". Wygenerujemy również dla nich pliki usług i kontrolerów.
Uruchom to polecenie, aby utworzyć moduł "module-a":
nest generate module module-a
Teraz utwórz moduł "module-b" za pomocą analogicznego polecenia:
nest generate module module-b
Następnie, użyj tej komendy, aby utworzyć pliki usług i kontrolera dla modułu "module-a":
nest generate service module-a && nest generate controller module-a
I powtórz ten sam krok dla modułu "module-b":
nest generate service module-b && nest generate controller module-b
Aktualna struktura projektu powinna wyglądać następująco, z katalogami "src/module-a" i "src/module-b":

Udostępnianie usługi z modułu A
Aby usługa z modułu "module-a" była dostępna dla innych modułów, należy ją uwzględnić w sekcji eksportu pliku modułu "module-a" (module-a.module.ts). Domyślnie, Nest.js CLI nie dodaje tablicy "exports" w dekoratorze "@Module", więc wygenerowany plik będzie wyglądać tak:
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 {}
Aby umożliwić innym modułom korzystanie z usługi "module-a.service.ts", musimy dodać tablicę "exports" do dekoratora "@Module" i umieścić w niej "ModuleAService".
Tak to wygląda:
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 {}
Następnie, dla celów demonstracyjnych, dodajmy prostą funkcję do pliku usługi "module-a" (module-a.service.ts):
import { Injectable } from '@nestjs/common';@Injectable()
export class ModuleAService {
getHello(): string {
return 'Hello from Module A!';
}
}
Ta funkcja zwraca przykładowy tekst. Aby sprawdzić, czy import usługi działa poprawnie, wywołamy tę funkcję z modułu "module-b" po wstrzyknięciu usługi "module-a".
Włączanie usługi w module B
Aby zaimportować moduł do innego modułu, musisz go dodać do sekcji "imports" w module docelowym. W naszym przypadku musimy dodać "module-a" do tablicy "imports" w dekoratorze "@Module" modułu "module-b".
Podobnie jak poprzednio, Nest.js CLI nie tworzy automatycznie tablicy "imports", więc trzeba ją dodać samodzielnie.
Najpierw zaimportuj moduł "module-a" (module-a.module.ts) do modułu docelowego (module-b.module.ts), utwórz tablicę "imports" i dodaj do niej "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 {}
Następnie, otwórz plik "module-b.service.ts" i zaimportuj dekorator "Inject" oraz "ModuleAService" odpowiednio z "@nestjs/common" i "../module-a/module-a.service":
import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from '../module-a/module-a.service';
Dekorator "Inject" oznacza parametr jako miejsce wstrzykiwania zależności.
Następnie, w klasie "ModuleBService", dodaj poniższy blok kodu:
@Inject(ModuleAService)
private readonly moduleAService: ModuleAService;
Powyższy kod umożliwia dostęp do metod w "ModuleAService" wewnątrz "ModuleBService".
Możesz teraz przetestować usługę, wywołując metodę "getHello" z "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();
}
}
Następnie, otwórz plik "module-b.controller.ts" i zastąp jego zawartość poniższym kodem:
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();
}
}
Powyższy fragment definiuje obsługę żądania GET dla ścieżki "/hello".
Na koniec, wykonaj żądanie GET za pomocą "curl" na "localhost:3000/module-b/hello". W odpowiedzi powinieneś zobaczyć na konsoli "Hello from Module A!".
Gratulacje, udało Ci się wstrzyknąć usługę do innego modułu! Jest to przydatne podczas tworzenia rozbudowanych API w Nest.js, gdzie wiele modułów musi współdzielić i wywoływać metody.
Zalety wstrzykiwania między modułami
Choć bezpośrednie wywoływanie usług z innych modułów może wydawać się łatwiejsze na początku, w dłuższej perspektywie może prowadzić do bardziej skomplikowanego, trudniejszego w utrzymaniu i mniej skalowalnego systemu.
Wstrzykiwanie między modułami promuje modułowość, ułatwia ponowne wykorzystanie kodu i jego konserwację. Ponadto centralizuje zależności, zwiększa testowalność oraz wspiera tworzenie architektury opartej na separacji warstw, co sprzyja skalowalności.