CQRS med ES

Hvad betyder disse forkortelser og hvorfor kan de være vigtige for mig?

Command Query Responsibility Segregation (CQRS) er en måde at opdele applikationsarkitektur, der sammenblander kendte patterns og practices, der længe har været brugt til at bygge skalerbare systemer. På nogle områder repræsenterer CQRS et brud med eksisterende tænkning, men muliggør til gengæld scenarier, der tidligere kun svært lod sig gøre. Event Sourcing (ES) repræsenterer også et brud med eksisterende tænkning i forhold til lagring af data. Frem for at gemme en aktuel tilstand af data, koncentrerer ES sig om at gemme de handlinger der forårsager skrift fra én tilstand til den næste. 

Traditionel lagdelt applikations arkitektur

Strukturen i en traditionel lagdelt applikation vil typsik kunne passe ind i nedenstående figur og lide af følgende svagheder (der formentlig vil blive forstærket over tid!).

  • For mange lag = kompleksitet.
  • Store uoverskuelige domæne modeller = større sandsynlighed for følgefejl ved ændringer i kodebasen.
  • Fokus på teknologistakken i stedet for på forretningen = kunden får ikke nok for sine penge.

Der vil være mange perspektiver på forretningsdata. En kunde vil forstå et ’Produkt’ på en anden måde end salgsafdelingen vil. Ét resultatet er, at datamodellen og domænemodellen skal være stor nok til at rumme alle perspektiver, men er det egentlig det vi ønsker? Et andet resultat er, at de forespørgelser der går gennem applikationen bliver rodet og skal tage højde for hvilke dele af data der skal tages med i en specifik kontekst. Løsningen kan kræve, at man skal accepterer et nyt tankesæt og være modtagelig for nye ideer!

CQRS

En given applikation skal normalt kunne understøtte use cases, der kan deles op i:

  • En bruger ønsker at ændre data.
  • En bruger ønsker at se data.

De enkelte klasser i enhver applikation understøtter ovenstående på Property niveau i form af deres Getter og Setter metodik. Det er denne tilgang der skal løftes op på et højere niveau. I CQRS skal metoder der skriver data seperares fra metoder der læser data ved at placerer dem i forskellige objekter:

  • Metoder der skriver data, kaldes Command metoder og må ikke returnerer en værdi.
    Formålet med en Command er at fange brugerens hensigt og understøtte en enkelt use case.
  • Metoder der læser data, kaldes Query metoder og må ikke ændre på data.
    Formålet med en Query er at fange brugerens behov og understøtte en enkelt use case.

Går CQRS og ES hånd i hånd?

Både CQRS og ES kan implementeres seperat, da de er to selvstændige metodikker, men kan ofte drage fordel af hianden. Netop når Commands dikterer én model til skrivning af data samtidig med at Queries kræver en anden model til læsning af data, kan ES anvendes til at bygge bro (løse den røde pil på nedenstående figur) mellem de 2 datamodeller.


ES

I ES vil data i databasen være overgangene mellem tilstande, der både kan servicerer Commands og Queries. Derved er ES blevet løsningen på behovet for synkronisering mellem data modeller i CQRS.

Kode eksempel

Nedenstående figur viser strukturen (fra Visual Studio 2010) for et simpelt eksempel på implementering af CQRS med ES over 2 tænkte forretningsobjekter: ‘Kunde’ og ‘Ordre’.

Hvis du gerne vil afprøve/kode videre på mit eksempel, kan du skrive til mig om at få tilsendt kodebasen.

Ulrich Landbo arbejder som software arkitekt ved Visma Consulting. Målet er at omsætte kunders forretningsbehov til kode af passende høj kvalitet. Midlerne er god kommunikation med kunder og kollegaer samt faglig inspiration på højt niveau. Han har meninger om arkitektur og kan udstikke en retning, men er ikke mere låst fast end at ham lytter til andre og løbende forbedre sine egne tanker og visioner.