CQRS- en CQS-benaderingen toepassen in een DDD-microservice in eShopOnContainers
Tip
Deze inhoud is een fragment uit het eBook, .NET Microservices Architecture for Containerized .NET Applications, beschikbaar op .NET Docs of als een gratis downloadbare PDF die offline kan worden gelezen.
Het ontwerp van de order microservice in de eShopOnContainers-referentietoepassing is gebaseerd op CQRS-principes. Het maakt echter gebruik van de eenvoudigste benadering, die alleen de query's van de opdrachten scheidt en dezelfde database gebruikt voor beide acties.
De essentie van deze patronen en het belangrijke punt hier is dat query's idempotent zijn: hoe vaak u een systeem opvraagt, verandert de status van dat systeem niet. Met andere woorden, query's zijn neveneffectvrij.
Daarom kunt u een ander gegevensmodel met leesbewerkingen gebruiken dan het transactionele logicadomeinmodel 'writes', ook al gebruiken de volgorde van microservices dezelfde database. Daarom is dit een vereenvoudigde CQRS-benadering.
Aan de andere kant veranderen opdrachten, die transacties en gegevensupdates activeren, de status in het systeem. Met opdrachten moet u voorzichtig zijn bij het omgaan met complexiteit en steeds veranderende bedrijfsregels. Hier wilt u DDD-technieken toepassen om een beter gemodelleerd systeem te hebben.
De DDD-patronen die in deze handleiding worden gepresenteerd, mogen niet universeel worden toegepast. Ze introduceren beperkingen voor uw ontwerp. Deze beperkingen bieden voordelen zoals een hogere kwaliteit in de loop van de tijd, met name in opdrachten en andere code die de systeemstatus wijzigt. Deze beperkingen voegen echter complexiteit toe met minder voordelen voor het lezen en opvragen van gegevens.
Een dergelijk patroon is het aggregatiespatroon, dat we in latere secties meer bekijken. Kort gezegd behandelt u in het patroon Aggregaat veel domeinobjecten als één eenheid als gevolg van hun relatie in het domein. Mogelijk profiteert u niet altijd van dit patroon in query's; het kan de complexiteit van querylogica verhogen. Voor alleen-lezenquery's krijgt u niet de voordelen van het behandelen van meerdere objecten als één aggregaties. Je krijgt alleen de complexiteit.
Zoals weergegeven in afbeelding 7-2 in de vorige sectie, wordt in deze handleiding voorgesteld om alleen DDD-patronen te gebruiken in het gebied transactionele/updates van uw microservice (dat wil gezegd, zoals geactiveerd door opdrachten). Query's kunnen een eenvoudigere aanpak volgen en moeten worden gescheiden van opdrachten, volgens een CQRS-benadering.
Voor het implementeren van de 'queryzijde' kunt u kiezen tussen veel benaderingen, vanuit uw volledige ORM, zoals EF Core, AutoMapper-projecties, opgeslagen procedures, weergaven, gerealiseerde weergaven of een micro ORM.
In deze handleiding en in eShopOnContainers (met name de bestellende microservice) hebben we ervoor gekozen om rechte query's te implementeren met behulp van een micro ORM zoals Dapper. In deze handleiding kunt u elke query implementeren op basis van SQL-instructies om de beste prestaties te krijgen, dankzij een licht framework met weinig overhead.
Wanneer u deze benadering gebruikt, hebben updates van uw model die van invloed zijn op hoe entiteiten worden bewaard in een SQL-database ook afzonderlijke updates nodig voor SQL-query's die worden gebruikt door Dapper of andere afzonderlijke (niet-EF)-benaderingen voor het uitvoeren van query's.
CQRS- en DDD-patronen zijn geen architecturen op het hoogste niveau
Het is belangrijk om te begrijpen dat CQRS en de meeste DDD-patronen (zoals DDD-lagen of een domeinmodel met aggregaties) geen architectuurstijlen zijn, maar alleen architectuurpatronen. Microservices, SOA en gebeurtenisgestuurde architectuur (EDA) zijn voorbeelden van architectuurstijlen. Ze beschrijven een systeem van veel onderdelen, zoals veel microservices. CQRS- en DDD-patronen beschrijven iets binnen één systeem of onderdeel; in dit geval iets in een microservice.
Verschillende gebonden contexten (PC's) maken gebruik van verschillende patronen. Ze hebben verschillende verantwoordelijkheden en dat leidt tot verschillende oplossingen. Het is de moeite waard om te benadrukken dat het afdwingen van hetzelfde patroon overal leidt tot fouten. Gebruik overal geen CQRS- en DDD-patronen. Veel subsystemen, PC's of microservices zijn eenvoudiger en kunnen eenvoudiger worden geïmplementeerd met eenvoudige CRUD-services of een andere benadering.
Er is slechts één toepassingsarchitectuur: de architectuur van het systeem of de end-to-end-toepassing die u ontwerpt (bijvoorbeeld de microservicesarchitectuur). Het ontwerp van elke gebonden context of microservice binnen die toepassing weerspiegelt echter zijn eigen compromissen en interne ontwerpbeslissingen op architectuurpatronenniveau. Probeer niet overal dezelfde architectuurpatronen toe te passen als CQRS of DDD.
Aanvullende bronnen
Martin Fowler. CQRS
https://martinfowler.com/bliki/CQRS.htmlGreg Young. CQRS-documenten
https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdfUdi Dahan. Verduidelijkte CQRS
https://udidahan.com/2009/12/09/clarified-cqrs/