Å integrere en tjeneste fra en annen Nest.js-modul krever noen få definerte trinn for å sikre at avhengighetsinjeksjonen og modulstrukturen er korrekt. Ved å utforske to eksempler på moduler, kan du forstå hvordan eksport og import av tjenester fungerer i praksis.
Opprettelse av et Nest.js-prosjekt
For å begynne med et nytt Nest.js-prosjekt, må du først ha Nest.js CLI installert på maskinen din. Hvis du ikke allerede har gjort det, bruk denne kommandoen for å installere den:
npm install -g @nestjs/cli
Når Nest.js CLI er installert, bruk denne kommandoen for å generere et nytt Nest.js-prosjekt:
nest new <prosjektnavn>
Du kan erstatte «<prosjektnavn>» med navnet du ønsker å bruke. Denne kommandoen vil opprette en ny Nest.js-prosjektmappe med det valgte navnet.
Prosjektstrukturen din vil nå se ut som illustrert i bildet nedenfor:
For å øve på å integrere en tjeneste fra en modul til en annen, skal vi opprette to nye moduler, kalt modul-a og modul-b. I tillegg skal vi også generere de tilhørende tjeneste- og kontrollerfilene for hver modul.
Bruk denne kommandoen for å opprette modul-a:
nest generate module module-a
Og tilsvarende, bruk denne for å opprette modul-b:
nest generate module module-b
Deretter bruker vi disse kommandoene for å generere tjeneste- og kontrollerfilene for modul-a:
nest generate service module-a && nest generate controller module-a
Og tilsvarende for modul-b:
nest generate service module-b && nest generate controller module-b
Nå vil prosjektstrukturen din inneholde src/module-a og src/module-b kataloger, som vist i bildet nedenfor:
Eksport av en tjeneste fra Modul A
For å eksportere modul-a-tjenesten fra modul-a, må den spesifiseres som en eksport i modul-a sin modulfil (module-a.module.ts). Som standard inkluderer ikke Nest.js CLI en eksportmatrise i @Module-dekoratoren, så den genererte modulfilen vil i utgangspunktet se slik ut:
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 {}
For å gjøre service-a (module-a.service.ts) tilgjengelig for andre moduler som importerer modul-a, må du legge til en eksportarray i @Module-dekoratoren og inkludere ModuleAService der.
Slik skal det se ut:
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 {}
For å verifisere at alt fungerer som det skal, kan du legge til en enkel funksjon i modul-a sin tjenestefil (module-a.service.ts):
import { Injectable } from '@nestjs/common';@Injectable()
export class ModuleAService {
getHello(): string {
return 'Hei fra Modul A!';
}
}
Denne funksjonen returnerer en enkel tekststreng. For å bekreft at du kan importere denne tjenesten på riktig måte, skal vi kalle denne funksjonen fra modul-b etter at du har integrert tjeneste-a.
Importering av en tjeneste til Modul B
For å importere en modul til en annen, må du spesifisere den som en import i importarrayen til den mottakende modulen. I dette tilfellet må du legge til modul-a i importarrayen til modul-b sin @Module-dekorator.
Som tidligere nevnt, genererer ikke Nest.js CLI automatisk en importmatrise, så denne må du legge til manuelt.
Først må du importere modul-a (module-a.module.ts) til den mottakende modulen (module-b.module.ts). Deretter oppretter du importarrayen og legger til ModuleAModule i den:
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 {}
Nå må du åpne module-b.service.ts-filen og importere Inject-dekoratoren og ModuleAService fra henholdsvis @nests/common og ../module-a/module-a.service:
import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from '../module-a/module-a.service';
Inject-dekoratoren signaliserer at parameteren er et mål for avhengighetsinjeksjon.
Deretter legger du til denne kodeblokken i ModuleBService-klassen din:
@Inject(ModuleAService)
private readonly moduleAService: ModuleAService;
Denne kodeblokken gir din ModuleBService tilgang til alle metodene som er definert i ModuleAService.
Du kan nå teste tjenesten ved å kalle getHello-metoden fra 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();
}
}
Til slutt, åpne module-b.controller.ts-filen og erstatt den genererte koden med følgende kodeblokk:
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();
}
}
Denne kodeblokken konfigurerer en GET-rutehandler for getHello-funksjonen.
Nå kan du teste dette ved å sende en GET-forespørsel med curl til localhost:3000/module-b/hello. Du skal nå få utskriften «Hei fra Modul A!» i konsollen din.
Du har nå integrert en tjeneste i en annen modul. Dette er nyttig når du utvikler API-er med Nest.js som har flere moduler som må kommunisere med hverandre.
Fordeler med kryssmodulinjeksjon
Selv om det i utgangspunktet kan virke enklere å kalle en tjeneste direkte fra en annen modul, kan det på sikt føre til et mer komplekst, vanskeligere å vedlikeholde og mindre skalerbart system.
Kryssmodulinjeksjon fremmer derimot kodemodularitet og gjenbrukbarhet, noe som forenkler vedlikehold. Det sentraliserer også avhengigheter, forbedrer testbarheten og støtter en mer skalerbar og frakoblet arkitektur.