Använd CQRS-mönstret med försiktighet och du kan skapa renare, mer skalbara Nest-appar.

Ett vanligt tillvägagångssätt för NestJS-utveckling är att bygga tjänster som kontrollerna kommunicerar med för att komma åt data. Men detta tillvägagångssätt är inte det enda giltiga designmönstret i NestJS. Det finns andra designmönster, till exempel CQRS designmönster.

CQRS är ett designmönster som separerar läs- och skrivoperationerna för en applikation. Denna separation kan bidra till att förbättra skalbarhet, prestanda och underhållsbarhet.

Ta reda på allt om CQRS och hur du kan tillämpa det när du bygger ett NestJS API.

Vad är CQRS?

CQRS står för kommando-förfrågan ansvarssegregering. Den implementerar användningen av kommandon för att skapa, uppdatera och ta bort data och frågor för att hämta data. Detta hjälper till att eliminera behovet av att implementera en applikations databasanrop i tjänster.

Det möjliggör också en tydlig åtskillnad mellan logiken i att fråga databasen efter data och att utföra andra åtgärder i en applikation.

instagram viewer

CQRS-metoden är användbar i domändriven design, som låter dig separera domänlogik och infrastrukturoperationer i din applikation. Du kan också använda den för att implementera komplex affärslogik, men detta rekommenderas inte för enklare applikationer.

Använder CQRS i ett NestJS API

Du kan använda CQRS-designmönstret i ett API som du bygger i NestJS. För att följa med behöver du ha Node.js installerat på din dator och en ny version av NestJS.

Använd följande steg för att bygga en enkel bloggapplikation som implementerar CQRS-designmönstret.

Skapa ett Nest-projekt

Skapa ett nytt Nest-projekt och generera ett posta resurs för en bloggapplikation. Du kan göra detta genom att köra följande kommandon i en terminal:

bygga nya nestjs-cqrs
bo g modul inlägg
bo g kontrollposter
bo g tjänsteposter

Installera beroenden

När du har slutfört stegen ovan, kör det här terminalkommandot för att installera NestJS CQRS-paketet:

npm installera --save @nestjs/cqrs

Skapa en posttjänst

Lägg till följande kod till din posts.service.ts fil för att definiera Postservice klass.

// posts.service.ts
importera { Injicerbar } från'@nestjs/common';

exporteragränssnitt Lägg upp {
titel: sträng;
innehåll: sträng;
}

@Injicerbar()
exporteraklass PostService {
privat skrivskyddade inlägg: Post[] = [];

skapa (post: Post): Post {
detta.posts.push (inlägg);
lämna tillbaka posta;
}

findById (id: siffra): Lägg upp {
lämna tillbakadetta.posts.find(posta => post.id id);
}
}

De Postservice definierar skapa och findById metoder för att skapa ett nytt inlägg och hämta ett befintligt inlägg från dess ID.

Definiera kommandon och frågor

Nästa steg är att definiera de frågor och kommandon som är kärnan i CQRS-designmönstret.

I den inlägg katalog, skapa två nya filer: skapaPostCommand.command.ts och getPostQuery.query.ts. Kommandofilen ska se ut så här:

// createPostCommand.command.ts
exporteraklass CreatePostCommand {
konstruktör(offentlig skrivskyddad titel: sträng, offentlig skrivskyddat innehåll: sträng) {}
}

Och frågedefinitionsfilen, så här:

// getPostQuery.query.ts
exporteraklass GetPostQuery {
konstruktör(offentlig skrivskyddat id: siffra) {}
}

Skapa kommando- och frågehanterare

När du har definierat dina kommandon och frågor måste du skapa hanterare för dem. En hanterare är en funktion som kör ett kommando eller en fråga och returnerar resultatet.

Skapa en hanterare.ts fil i din posta katalog och klistra in följande kod i den:

// handlers.ts
importera { CommandHandler, ICommandHandler } från'@nestjs/cqrs';
importera { CreatePostCommand } från'./createPostCommand.command.ts';
importera { PostService } från'./post.service';

@CommandHandler(CreatePostCommand)
exporteraklass Skapa PostHandler redskap ICommandHandler {
konstruktör(privat skrivskyddad postService: PostService) {}

asynkron exekvera (kommando: CreatePostCommand) {
konst { namn, pris } = kommando;
konst inlägg = väntadetta.postService.create (titel, innehåll);
lämna tillbaka posta;
}
}

I samma hanterare.ts fil, kan du modifiera importsatserna så att de inkluderar de nedan för att tillåta arbete med frågor. Du kan sedan implementera frågehanteraren som visas i koden nedan:

// handler.ts
importera { QueryHandler, IQueryHandler } från'@nestjs/cqrs';
importera { GetPostQuery } från'./getPostQuery.query';
importera { PostService } från'./post.service';

// frågehanterare
@QueryHandler(GetProductQuery)
exporteraklass GetPostHandler redskap IQueryHandler {
konstruktör(privat skrivskyddad postService: PostService) {}

asynkron exekvera (fråga: GetPostQuery) {
konst { id } = fråga;
konst inlägg = väntadetta.postService.findOneById (id);
lämna tillbaka posta;
}
}

Registrera Handlers

Det sista steget är att registrera kommando- och frågehanterarna med NestJS-modulen.

// post.module.ts
importera { Modul } från'@nestjs/common';
importera { CommandHandlers, QueryHandlers } från"handlers.ts";
importera { PostService } från'./post.service';

@Modul({
leverantörer: [
Postservice,
...CommandHandlers,
...QueryHandlers,
],
})
exporteraklass PostModule {}

Denna kod registrerar Postservice, CommandHandlers, och QueryHandlers i leverantörer array. Användningen av en spridningsoperatör (...) är att slå samman arrayerna av fråga hanterare och kommando hanterare i leverantörer array.

Utför kommandon och frågor

De registrerade kommandona och frågehanterarna är användbara i styrenheter. Följande kod är implementeringen av en inlägg kontroller som accepterar HTTP-förfrågningar och returnerar nödvändiga svar.

// posts.controller.ts
importera { Body, Controller, Post } från'@nestjs/common';
importera { CommandBus } från'@nestjs/cqrs';
importera { CreatePostCommand } från'./createPostCommand.command.ts';

// styrenhet som implementerar kommando
@Kontroller("inlägg")
exporteraklass PostController {
konstruktör(privat skrivskyddad commandBus: CommandBus) {}

@Posta()
asynkron skapa inlägg(@Kropp() body: { title: sträng; innehåll: sträng }) {
konst { title, content } = body;
konst kommando = ny CreatePostCommand (titel, innehåll);
konst inlägg = väntadetta.commandBus.execute (kommando);
lämna tillbaka posta;
}
}

I koden ovan visas CommandBus utför CreatePostCommand och skapar ett nytt inlägg.

Den här koden visar hur man implementerar en kontroller som använder en fråga:

// posts.controller.ts
importera { Controller, Get, Param } från'@nestjs/common';
importera { QueryBus } från'@nestjs/cqrs';
importera { GetPostQuery } från'./getPostQuery.query';

@Kontroller("inlägg")
exporteraklass PostController {
konstruktör(privat skrivskyddad queryBus: QueryBus) {}

@Skaffa sig(':id')
asynkron getPost(@Param('id') id: siffra) {
konst fråga = ny GetPostQuery (id);
konst inlägg = väntadetta.queryBus.execute (fråga);
lämna tillbaka posta;
}
}

De queryBus avrättar GetPostQuery som får inlägget med angivet ID och returnerar det.

Efter att ha slutfört alla steg ovan bör du nu ha en minimalistisk, fungerande applikation för att skapa och hämta blogginlägg.

Även om koden här använder en array för att lagra de skapade inläggen i minnet, är det mer sannolikt att du använder en databas i produktionen. Du kan antingen använda en SQL-databas, eller a NoSQL-databas som MongoDB, eftersom NestJS stöder båda alternativen.

Bygga API: er med CQRS Design Pattern

Att integrera CQRS-designmönstret i din NestJS-applikation kan hjälpa till med skalbarhet, prestanda och underhållsbarhet. CQRS möjliggör effektivare och optimerade operationer genom att separera läs- och skrivoperationerna som en applikation utför.

Paketet @nestjs/cqrs tillhandahåller en byggsten för att implementera CQRS i NestJS med kommandon och frågehanterare. Sammantaget är CQRS ett kraftfullt mönster som kan hjälpa till att skapa mer effektiva och skalbara applikationer, och du bör väga upp dina alternativ innan du använder det.