Část 06 z 16 · Den 1 · CQRS, projekce

Stav rozesetý po službách

Problém a zkušenost

Klient neví, v jakém stavu žádost je

Odpověď na „Kde je moje žádost?“ je rozeseta po několika službách.

  1. Riskposuzuje
  2. Approvalčeká
  3. Identityještě ne
  4. Klient„Kde je moje žádost?“

Čtení z write modelu

  1. Dotaz
  2. Přehrání 251 událostí
  3. Odpověď

Zkušenost z praxeJak dlouho u vás trvá odpovědět klientovi, v jakém stavu je jeho žádost?

TakeawayCo dobře ukládá změny, nemusí dobře odpovídat na otázky.

Více k tématu

Co to znamená

Zápisový model hlídá pravidla. Čtení potřebuje jiný tvar: souhrn, seznam, stav pro klienta.

Proč to používáme

Když oba úkoly vtěsnáme do jednoho modelu, každý dělá kompromisy.

Kdy to dává smysl

Když se čtení a zápis opravdu liší: tvar dat, zátěž, dostupnost.

Kde se to láme

  • Čtení z event store přehráním pro každý dotaz.
  • Dělat CQRS u jednoduchého CRUD, kde se čtení a zápis neliší.

Představme si

Poradce otevře kalkulaci. Systém přehraje 251 událostí, aby ukázal jednu obrazovku.

Nejde o to mít dva modely. Jde o to, aby každý dělal jen jednu práci.

Princip, aplikace a cvičení

Příkaz mění, dotaz čte

Zápis a čtení mají vlastní modely. Spojuje je událost a projekce.

  1. CommandChangeIncome
  2. Write modelhlídá pravidla
  3. EventIncomeChanged
  4. Projectionstaví pohled
  5. Read modeltvar pro dotaz
  6. QueryGetCalculation

Co kudy teče

  1. Příkaz vrací jen potvrzení a verzi
  2. Dotaz nic nemění

TakeawayCommand → Write model → Event → Projection → Read model → Query.

Více k tématu

Co to znamená

CQRS (Command Query Responsibility Segregation) odděluje dvě práce: změnit stav a přečíst stav. Čtecí model (projekce) se staví z událostí.

Proč to používáme

Čtecí model se navrhuje podle toho, co obrazovka potřebuje. Zápisový zůstává čistý.

Kdy to dává smysl

Když se potřeby čtení a zápisu liší nebo když čtení potřebuje škálovat zvlášť.

Kde se to láme

  • Příkaz nesmí číst z čtecího modelu, aby rozhodl o zápisu.
  • Příkaz, který vrací celý čtecí model, obě strany zase spojí.

Představme si

Změna příjmu jde přes příkaz. Obrazovka kalkulace čte projekci, která už má spočítanou splátku a DTI.

Spojnicí mezi oběma stranami je událost, ne sdílená tabulka.

Princip, aplikace a cvičení

Čtecí model je chvíli pozadu

Po příkazu projekce ještě nestihla změnu zpracovat. Zpoždění se dá měřit a ošetřit tokenem verze. CQRS není Event Sourcing.

Bez ošetření

  1. Commandpříjem 95 000 → v252
  2. Query hnedčte v251
  3. Uživatel nevidí svou změnu

S read-your-writes

  1. Commandvrací v252
  2. Query minVersion=252počká na projekci
  3. Aktuální data

CQRS bez Event Sourcingu

  1. Command
  2. Tabulkawrite model
  3. CalculationChangedudálost při zápisu
  4. Read model

Trade-offVíce modelů a eventual consistency: čtení je pozadu a UI s tím musí počítat. CQRS nemusí zrychlit, jen oddělit.

TakeawayZpoždění není chyba. Chybou je, když s ním UI nepočítá. A CQRS jde použít s Event Sourcingem i bez něj.

Více k tématu

Co to znamená

Eventual consistency: čtecí model dožene zápis, ale ne okamžitě. Zpoždění měříme jako počet verzí a milisekundy. Příkaz vrací číslo verze a dotaz s minVersion buď počká, nebo vrátí příznak, že data jsou starší.

Proč to používáme

Jinak uživatel po uložení vidí staré číslo a myslí si, že se změna nepovedla.

Kdy to dává smysl

Vždy, když čtení nejde do stejné transakce jako zápis.

Kde se to láme

  • Čekat bez limitu. Dotaz musí mít timeout.
  • Ukazovat zastaralá data bez upozornění.
  • Neměřit zpoždění projekce.
  • Zaměnit CQRS s Event Sourcingem.

Představme si

Poradce změní příjem a hned načte kalkulaci. Bez ošetření vidí starou splátku. V labu přepněte „Zápisový model bez Event Sourcingu“: tok i zpoždění zůstanou stejné.

Cenou za oddělení je čas. Zaplatíme ji vědomě, ne překvapením.

Školení pro váš tým

Chcete školení pro svůj tým?

Školení vedeme na vašem kódu a vašem doménovém problému. Domluvíme rozsah, termín a formu.

Probrat školení