Injisér NestJS-tjenester: Komplett guide med eksempler

Å 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.