Dela via


Tillämpa förenklade CQRS- och DDD-mönster i en mikrotjänst

Dricks

Det här innehållet är ett utdrag från eBook, .NET Microservices Architecture for Containerized .NET Applications, tillgängligt på .NET Docs eller som en kostnadsfri nedladdningsbar PDF som kan läsas offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

CQRS är ett arkitekturmönster som separerar modellerna för att läsa och skriva data. Den relaterade termen Command Query Separation (CQS) definierades ursprungligen av Bertrand Meyer i hans bok Object-Oriented Software Construction. Den grundläggande tanken är att du kan dela upp ett systems åtgärder i två kraftigt avgränsade kategorier:

  • Frågor. Dessa frågor returnerar ett resultat och ändrar inte systemets tillstånd, och de är fria från biverkningar.

  • Kommandon. Dessa kommandon ändrar tillståndet för ett system.

CQS är ett enkelt begrepp: det handlar om metoder inom samma objekt som antingen är frågor eller kommandon. Varje metod returnerar antingen tillstånd eller muterar tillstånd, men inte båda. Även ett enskilt databasmönsterobjekt kan följa CQS. CQS kan betraktas som en grundläggande princip för CQRS.

Kommando- och frågeansvarssegregering (CQRS) introducerades av Greg Young och marknadsfördes starkt av Udi Dahan och andra. Den baseras på CQS-principen, även om den är mer detaljerad. Det kan betraktas som ett mönster baserat på kommandon och händelser plus valfritt på asynkrona meddelanden. I många fall är CQRS relaterat till mer avancerade scenarier, som att ha en annan fysisk databas för läsningar (frågor) än för skrivningar (uppdateringar). Dessutom kan ett mer utvecklat CQRS-system implementera Event-Sourcing (ES) för din uppdateringsdatabas, så att du bara lagrar händelser i domänmodellen i stället för att lagra aktuella data. Den här metoden används dock inte i den här guiden. Den här guiden använder den enklaste CQRS-metoden, som består av att bara separera frågorna från kommandona.

Separationsaspekten för CQRS uppnås genom att gruppera frågeåtgärder i ett lager och kommandon i ett annat lager. Varje lager har en egen datamodell (observera att vi säger modell, inte nödvändigtvis en annan databas) och skapas med sin egen kombination av mönster och tekniker. Ännu viktigare är att de två lagren kan ligga inom samma nivå eller mikrotjänst, som i exemplet (beställa mikrotjänst) som används för den här guiden. Eller så kan de implementeras på olika mikrotjänster eller processer så att de kan optimeras och skalas ut separat utan att påverka varandra.

CQRS innebär att ha två objekt för en läs-/skrivåtgärd där det i andra sammanhang finns ett. Det finns skäl att ha en avnormaliserad läsningsdatabas, som du kan lära dig mer om i mer avancerad CQRS-litteratur. Men vi använder inte den metoden här, där målet är att ha mer flexibilitet i frågorna i stället för att begränsa frågorna med begränsningar från DDD-mönster som aggregeringar.

Ett exempel på den här typen av tjänst är att beställa mikrotjänster från referensprogrammet eShopOnContainers. Den här tjänsten implementerar en mikrotjänst baserat på en förenklad CQRS-metod. Den använder en enda datakälla eller databas, men två logiska modeller plus DDD-mönster för transaktionsdomänen enligt bild 7–2.

Diagram showing a high level Simplified CQRS and DDD microservice.

Bild 7-2. Förenklad CQRS- och DDD-baserad mikrotjänst

Den logiska mikrotjänsten "Beställning" innehåller dess beställningsdatabas, som kan vara, men inte behöver vara, samma Docker-värd. Att ha databasen i samma Docker-värd är bra för utveckling, men inte för produktion.

Programlagret kan vara själva webb-API:et. Den viktiga designaspekten här är att mikrotjänsten har delat upp frågorna och ViewModels (datamodeller som särskilt skapats för klientprogrammen) från kommandona, domänmodellen och transaktionerna enligt CQRS-mönstret. Den här metoden håller frågorna oberoende av begränsningar och begränsningar som kommer från DDD-mönster som bara är meningsfulla för transaktioner och uppdateringar, enligt beskrivningen i senare avsnitt.

Ytterligare resurser