Čá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.
- Riskposuzuje
- Approvalčeká
- Identityještě ne
- Klient„Kde je moje žádost?“
Čtení z write modelu
- Dotaz
- Přehrání 251 událostí
- 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.
- CommandChangeIncome
- Write modelhlídá pravidla
- EventIncomeChanged
- Projectionstaví pohled
- Read modeltvar pro dotaz
- QueryGetCalculation
Co kudy teče
- Příkaz vrací jen potvrzení a verzi
- 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í
- Commandpříjem 95 000 → v252
- Query hnedčte v251
- Uživatel nevidí svou změnu
S read-your-writes
- Commandvrací v252
- Query minVersion=252počká na projekci
- Aktuální data
CQRS bez Event Sourcingu
- Command
- Tabulkawrite model
- CalculationChangedudálost při zápisu
- 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í →