Wees voorzichtig met het CQRS-patroon en je kunt schonere, beter schaalbare Nest-apps maken.
Een gebruikelijke benadering van NestJS-ontwikkeling is het bouwen van services waarmee controllers communiceren om toegang te krijgen tot gegevens. Maar deze benadering is niet het enige geldige ontwerppatroon in NestJS. Er zijn andere ontwerppatronen, zoals het CQRS-ontwerppatroon.
CQRS is een ontwerppatroon dat de lees- en schrijfbewerkingen van een toepassing scheidt. Deze scheiding kan de schaalbaarheid, prestaties en onderhoudbaarheid helpen verbeteren.
Lees alles over CQRS en hoe u dit kunt toepassen bij het bouwen van een NestJS API.
Wat is CQRS?
CQRS betekent scheiding van verantwoordelijkheden voor commando's. Het implementeert het gebruik van commando's om gegevens aan te maken, bij te werken en te verwijderen en vragen om gegevens op te halen. Dit helpt de noodzaak weg te nemen om de database-oproepen van een applicatie naar services te implementeren.
Het maakt ook een duidelijk onderscheid mogelijk tussen de logica van het opvragen van gegevens in de database en het uitvoeren van andere acties in een toepassing.
De CQRS-benadering is nuttig in domeingestuurd ontwerp, waarmee u domeinlogica en infrastructurele bewerkingen in uw toepassing kunt scheiden. U kunt het ook gebruiken om complexe bedrijfslogica te implementeren, maar dit wordt niet aanbevolen voor eenvoudigere toepassingen.
CQRS gebruiken in een NestJS API
U kunt het CQRS-ontwerppatroon gebruiken in een API die u in NestJS bouwt. Om mee te volgen, moet je hebben Node.js op uw computer geïnstalleerd en een recente versie van NestJS.
Gebruik de volgende stappen om een eenvoudige blogtoepassing te bouwen die het CQRS-ontwerppatroon implementeert.
Maak een Nest-project
Maak een nieuw Nest-project en genereer een na bron voor een blogtoepassing. U kunt dit doen door de volgende opdrachten in een terminal uit te voeren:
nest nieuw nestjs-cqrs
nest g module berichten
nest g-controllerposten
nest g dienstposten
Afhankelijkheden installeren
Nadat u de bovenstaande stappen heeft voltooid, voert u deze terminalopdracht uit om het NestJS CQRS-pakket te installeren:
npm install --save @nestjs/cqrs
Maak een postservice
Voeg de volgende code toe aan uw posts.service.ts bestand om de Postdienst klas.
// posts.service.ts
importeren { Injecteerbaar } van'@nestjs/common';exporterenkoppel Na {
titel: snaar;
inhoud: snaar;
}@Injecteerbaar()
exporterenklas Postdienst {
privaat alleen-lezen berichten: Bericht[] = [];maken (post: Post): Post {
dit.posts.push (posten);
opbrengst na;
}
findById (id: nummer): Na {
opbrengstdit.posts.vinden(na => post.id id);
}
}
De Postdienst definieert creëren En vindById methoden om een nieuw bericht te maken en een bestaand bericht van zijn ID te halen.
Definieer opdrachten en vragen
De volgende stap is het definiëren van de query's en commando's die de kern vormen van het CQRS-ontwerppatroon.
In de posten directory, maak twee nieuwe bestanden aan: creërenPostCommand.command.ts En getPostQuery.query.ts. Het opdrachtbestand zou er als volgt uit moeten zien:
// createPostCommand.command.ts
exporterenklas CreatePostCommand {
constructeur(openbaar alleen-lezen titel: snaar, openbaar alleen-lezen inhoud: snaar) {}
}
En het querydefinitiebestand, zoals dit:
// getPostQuery.query.ts
exporterenklas GetPostQuery {
constructeur(openbaar alleen-lezen-ID: nummer) {}
}
Maak opdracht- en queryhandlers
Nadat u uw opdrachten en query's met succes hebt gedefinieerd, moet u er handlers voor maken. Een handler is een functie die een opdracht of query uitvoert en de uitkomst retourneert.
Maak een handlers.ts bestand in uw na directory en plak de volgende code erin:
// handlers.ts
importeren { CommandHandler, ICommandHandler} van'@nestjs/cqrs';
importeren { CreatePostCommand } van'./createPostCommand.command.ts';
importeren { Postdienst } van'./Postdienst';@CommandHandler(CreatePostCommand)
exporterenklas CreatePostHandler implementeert ICommandHandler{
constructeur(privaat alleen-lezen postService: PostService) {}
asynchroon uitvoeren (opdracht: CreatePostCommand) {
const { naam, prijs } = opdracht;
const plaatsen = wachtendit.postService.create (titel, inhoud);
opbrengst na;
}
}
In hetzelfde handlers.ts bestand, kunt u de importinstructies wijzigen om onderstaande op te nemen, zodat u met query's kunt werken. U kunt dan de queryhandler implementeren zoals te zien in de onderstaande code:
// handler.ts
importeren {QueryHandler, IQueryHandler} van'@nestjs/cqrs';
importeren {GetPostQuery} van'./getPostQuery.query';
importeren { Postdienst } van'./Postdienst';// query-handler
@QueryHandler(GetProductQuery)
exporterenklas GetPostHandler implementeert IQueryHandler{
constructeur(privaat alleen-lezen postService: PostService) {}
asynchroon uitvoeren (query: GetPostQuery) {
const { id } = vraag;
const plaatsen = wachtendit.postService.findOneById (id);
opbrengst na;
}
}
Handlers registreren
De laatste stap is het registreren van de opdracht- en queryhandlers bij de NestJS-module.
// post.module.ts
importeren { Module } van'@nestjs/common';
importeren { CommandHandlers, QueryHandlers } van'handlers.ts';
importeren { Postdienst } van'./Postdienst';
@module({
aanbieders: [
Postdienst,
...CommandHandlers,
...QueryHandlers,
],
})
exporterenklas Postmodule {}
Deze code registreert de Postdienst, CommandHandlers, En QueryHandlers in de aanbieders reeks. Het gebruik van een spread-operator (...) is om de arrays van samen te voegen vraag behandelaars en commando begeleiders in de aanbieders reeks.
Voer opdrachten en vragen uit
De geregistreerde commando's en query-handlers zijn bruikbaar in controllers. De volgende code is de implementatie van een posten controller die HTTP-verzoeken accepteert en de vereiste antwoorden retourneert.
// posts.controller.ts
importeren { Lichaam, controleur, post } van'@nestjs/common';
importeren { CommandBus } van'@nestjs/cqrs';
importeren { CreatePostCommand } van'./createPostCommand.command.ts';// controller die commando implementeert
@Beheerder('berichten')
exporterenklas PostController {
constructeur(privaat alleen-lezen commandBus: CommandBus) {}
@Na()
asynchroon maakPost(@Lichaam() hoofdtekst: {titel: snaar; inhoud: snaar }) {
const { titel, inhoud } = hoofdtekst;
const commando = nieuw CreatePostCommand (titel, inhoud);
const plaatsen = wachtendit.commandBus.execute (opdracht);
opbrengst na;
}
}
In de bovenstaande code is de CommandBus voert de CreatePostCommand en maakt een nieuw bericht aan.
Deze code laat zien hoe een controller moet worden geïmplementeerd die een query gebruikt:
// posts.controller.ts
importeren { Controller, Get, Param } van'@nestjs/common';
importeren {QueryBus} van'@nestjs/cqrs';
importeren {GetPostQuery} van'./getPostQuery.query';@Beheerder('berichten')
exporterenklas PostController {
constructeur(privaat alleen-lezen queryBus: QueryBus) {}
@Krijgen(':ID kaart')
asynchroon haalPost(@Param('ID kaart') ID kaart: nummer) {
const vraag = nieuw GetPostQuery (id);
const plaatsen = wachtendit.queryBus.execute (vraag);
opbrengst na;
}
}
De queryBus voert uit GetPostQuery die de post met de opgegeven ID krijgt en retourneert.
Nadat je alle bovenstaande stappen hebt voltooid, zou je nu een minimalistische, werkende applicatie moeten hebben om blogposts te maken en op te halen.
Hoewel de code hier een array gebruikt om de gemaakte berichten in het geheugen op te slaan, is de kans groter dat u een database in productie gebruikt. U kunt ofwel een SQL-database, of een NoSQL-database zoals MongoDB, aangezien NestJS beide opties ondersteunt.
API's bouwen met het CQRS-ontwerppatroon
Het opnemen van het CQRS-ontwerppatroon in uw NestJS-toepassing kan helpen bij schaalbaarheid, prestaties en onderhoudbaarheid. CQRS zorgt voor efficiëntere en geoptimaliseerde bewerkingen door de lees- en schrijfbewerkingen die een toepassing uitvoert te scheiden.
Het pakket @nestjs/cqrs biedt een bouwsteen voor het implementeren van CQRS in NestJS met opdrachten en queryhandlers. Over het algemeen is CQRS een krachtig patroon dat kan helpen bij het creëren van efficiëntere en schaalbare applicaties, en u moet uw opties afwegen voordat u het gebruikt.