CQRS recipes or how to cook your architecture
@tjaskula
But before we dive into CQRS recipes…
…we have to understand basic layered ones
Maslow pyramid in meal recipesNot official, just my own trip
Culinary art
Fine food
Home cooking
Fast food and frozen food
Basic ingredients like milk, bread, meat
Hey! How this relates to architecture mate?
Maslow architecture pyramid?This should somehow map
?
?
?
?
?
Culinary art
Fine food
Home cooking
Fast food and frozen food
Basic ingredients like milk, bread, meat
But first let’s tell a little story…
…of one e-commerce application that I’ve learnt so hard
Once upon a time… a marketing team came in
…to announce to developers what they have sold
“We need an e-commerce portal. Now!”
“Do it fast”
“We need every feature Orders, Product catalog, Suppliers”
Development has started…
In progress…
…Then the developer has came after a while…
E-Commerce portal architecture
UI
Domain
DAL
DB
Another feature was asked by the business…
But developers just…
It will take another year. Because we’ve built a…
“We need to refactor. Business want’s more features…”
How to refactor a monolith?
To decouple every component, you have.
Evolve domainindependently, it should.
Handle business needs easier, you will.
Decouple components
Handle business logic in isolated domain
We have to think it over, but for now let’s wrap up what we’ve learnt
Write unit test because every change is a breaking one
Lesson learnt 1
Simple architecture, does not scale, hard to maintain, often monolithic
Recipe 1:Basic layered architecture
Recipe 1
Basic layered architecture
Ingredients
Basic coding skillsSome infrastructure pieces (DB, etc.)
Client reviews
• Can be set up very quickly• Easy to understand• No need for experienced developers. Juniors can make it
• Leads quickly to unmaintainable monolith code blocks• Not easily evolvable for quickly changing business requirements• Not scalable• Not performent if charge gets bigger• Not testable. You’d better have end-to-end integration tests
Difficulty:
Time: from 25 min to infinityPreparation:Just throw basic code skills in. Mix it up with a database and UI and everything will be fine…or not…
UI
Domain
DAL
DB
Where we’ve been?
Ah yeah…DECOUPLING stuff
Then this came in
Let’s decouple ourselves from DB
And decouple us from everything else…
IoC container FTW!
And…
And…
Business ask more futures for Orders, Suppliers, stuff…
UI
OrderViewModel
Order
OrderController
OrderMapper IOrderMapper
SqlOrderRepository IOrderRepository
DB
Pre
sen
tati
on
Do
mai
nIn
fras
tru
ctu
re
Architecture v2
What's the problem with n-layered architectures?
What's the problem with n-layered architectures ?
Reused Abstraction Principle
VIOLATED
Over time, more features, more pain…
Because of…
public class OrderController {
public OrderController (IOrderValidator order validator,IOrderMapper orderMapper,IOrderRepository orderRepositoryISupplierRepository supplierRepositoryIAuthorizationFactory authorizationFactory,IUnitOfWork unitOfWork,IUserFactory userFactoryISession session,ILogger logger,IOrderCache orderCache) {
}}
And because developers spent their time on…
It seems that after a while we have still a monolith
But decoupled
We need more data on UI and different views per user…
But our model doesn’t support it
Every time we add a new view our model is broken…
Views are slower. Users complain…
Your reads from writes separate. Herh herh herh.
CQRS, you will do !
We have to think about it…
Time to wrap up…
Lesson learnt 2
Domain centric, refactorable and evolvable
Simple architecture, does not scale, hard to maintain, often monolithic
Recipe 1:Basic layered architecture
Recipe 2:n-layered architecture with DI
Recipe 2
N-layered architecture with DI
Ingredients
OOP skillsWith SOLID principles would be event betterORMs and IOCsSome infrastructure pieces (DB, etc.)
Client reviews
• Can be set up rather quickly• Easy to understand• Can be tested
• Can lead to unmaintainable monolith code blocks• Not easily evolvable for quickly changing business requirements• Not scalable• Not performent if charge gets bigger
Difficulty:
Time: reasonablePreparation:One must know OOP concepts and the best would be also to be aware of SOLID principles…
UI
OrderViewModel
Order
OrderController
OrderMapper IOrderMapper
SqlOrderRepository
IOrderRepository
DB
Where we’ve been?
Ah yeah…CQRS stuff
What is CQRS?
CQS applied to architecture = CQRS
Split Read from Writes
UI
Domain
Repository
DB Write DB Read
Read Model Application service
Command Query
Architecture v3
Command
UI
Domain
Repository
DB Write
Read Model Application service
DB Read denormalized
Query
Architecture v3 bis
Wow, the speed of views has increased
We can scale up read and write side independently
Easy to handle more business request about views and queries in denormalized DB
Even of it’s better we still have problems
Why we have impacts between different business lines?
Why it takes so much time for a new feature? And we always don’t get exactly what we want. There is always a confusion.
Integration inside of the business
CRUD events ?CQRS not a top level architecture
Composite UI
UI
Data Access Layer
Web / Application Tier
Background server Tier
Storage Tier
DDD layeredapplication
Writemodel
Readmodel
Legacy application
Domain A Domain B Domain C Domain D
CRUD architecture (simple non-core domain
functionality)
DDD (core domainfunctionality)
CQRS (core domainfunctionality)
Legacy subsystem
How to know where to put the effort?
What is the strategic advantage of my company?
Order management system is our strategic goal…
Great then we know where to put our effort…
But how do we find the best model for a business…
To them about events talk.
Find it meaningful, will they. Yeesssssss.
The quest has started
Event Storming = Domain Discovery Tool
source : Brandolini http://bit.ly/1s1dwoB
Events, that’s the way we think about it!
From events, to aggregates…It’s DDD!
Domain Driven DesignIt’s much more than just commands and events
• Ubiquitous Language
• Bounded Context
• Context Map
• Domain Event
• Aggregates
We need a new feature concert ticket sell
Done!
System is unusable users are blocked!!!
Ah no, what to do?
Express business intent in commands and facts in events, you will.
Make events asynchronous, you will. Herh herh herh.
We have to think about it…
Time to wrap up…
Lesson learnt 3
Decoupled and easy to integrate with external
systems
Domain centric, refactorableand evolvable
Simple architecture, does not scale, hard to maintain, often monolithic
Recipe 1:Basic layered architecture
Recipe 2:n-layered architecture with DI
Recipe 3:Hexagonal with basic CQRS
Recipe 3
Basic CQRS
Ingredients
OOP skillsSOLID principlesDomain Driven Design would be a big advantage
Client reviews
• Scale out read from writes independently• Can handle more business request about queries• More maintainable code• Even easier to test
•Users still can be blocked read and write are synchronous• Not so performent for big charges
Difficulty:
Time: mid-termPreparation:Establish a ubiquitous language with your domain experts and express it in the code
UI
Domain
Repository
DB Write
Read Model
Application service
DB Rea
ddenormalized
Where we’ve been?
Ah yeah commands and events…asynchronous
Command, it’s business intent like “Place Order”
Event, it’s business immutable fact like “OrderPlaced”
Architecture v4
Domain Repository
DB Write
Read Model Application service
DB Read
UI
Command Handler
Command Bus
Event Bus
Read model generator
Another context application
Command
Event
Dependency
Domain Repository
DB Write
Read Model Application service
DB Read DB Write
Read Model Application service
DB Read
Command Handler
Command Bus
Event Bus
Read model generator
ACL
Command Handler
Domain RepositoryRead model generator
UI
Command
Event
Dependency
Architecture v4’
Domain Repository
DB Write
Read Model Application service
DB Read DB Write
Application service
UI
Command Handler
Command Bus
Event Bus
Read model generator
ACL
Command Handler
Domain Repository
Command
Event
Dependency
Architecture v4’’
But there is a trap. Views are not refreshed immediately
CAP Theorem*CQRS Ingredients
Consistency:A read sees all previously completed writes
Availability:Reads and writes always succeed
Partition tolerance:Guaranteed properties are maintained even when network failures prevent some machines from communicating with others
* Eric Brewer
A system can be either CP, AP. CA is not coherent.
CAP TheoremCQRS Ingredients
CP AP
Node 1 Node 2 Node 1 Node 2
Data Data Data Data
Eventual ConsistencyCQRS Ingredients
« A key benefit of embracing eventual consistency is to remove the requirement for using distributed transactions »
Users deal every day with Eventual Consistency
But there is still a trap with event synchronization
Write side Read side
UI
Write Model
DB Write
Read Model
DB Read
Update write sidedata store Update read side
data store
Read data
Transaction Scope
Write side Read side
UI
Write Model
DB Write
Read Model
DB Read
Update write sidedata store
Send message to update read sidedata store
Read data
Transaction Scope
Event BusReliable messaging
Write side Read side
UI
Write Model
DB Write
Read Model
DB Read
Update write sidedata store
Send message to update read sidedata store
Read data
Transaction Scope
Event BusReliable messaging
I would like to know if user before placing an Order removes Items if we propose them more useful articles with our recommendation system
That’s a tricky question. We don’t have a history.
All you need, you have.Use your events, you will. Yeesssssss.
We have to think about it…
Time to wrap up…
Lesson learnt 4
Easily scalable and
preferment
Decoupled and easy to integrate with external
systems
Domain centric, refactorableand evolvable
Simple architecture, does not scale, hard to maintain, often monolithic
Recipe 1:Basic layered architecture
Recipe 2:n-layered architecture with DI
Recipe 3:Hexagonal with basic CQRS
Recipe 4:Hexagonal’ish with CQRS + DDD
Recipe 4
Basic CQRS + DDD + Async
Ingredients
Good OOP skillsSOLID principlesDomain Driven Design modelingGood knowledge of messaging infrastructure
Client reviews
• Handles concurrent domains• Scale out read from writes independently• Can handle more business request about queries• Business process explicit• Even easier to test
• Many moving parts• Sometimes integration points between systems are harder to grasp• Bad things can happen if no integration events command are stored
Difficulty:
Time: long termPreparation:Gather business intent in form of Commands, map it to business events and synchronize everything async.
DomainReposito
ry
DB Write
Read Model Application
service
DB Read
DB Write
Application service
UI
Command Handler
Command Bus
Event Bus
Read model
generator
ACL
Command Handler
DomainReposito
ry
Where we’ve been?
Ah yeah storing events…
For legal thing, we would like an audit log
If we got a time machine…
Yes you have it. Events = facts
Event SourcingCQRS Ingredients
Event as a storage mechanism
OrderOrder line
Item
Shipping information
Order Created
Added 2 items 245
Added 3 items 455
Removed 2 items 245
Added shipping info
Order placed
Event Sourcing
Rolling snapshot
Order Created
Added 2 items 245
Added 3 items 455
Removed 2 items 245
Added shipping info
Order placed
Snapshot
Put on stack Added 3 items 455
Removed 2 items 245
Added shipping info
Order placed
Snapshot
Domain
Event Store
Read Model Application service
DB Read
UI
Command Handler
Command Bus
Event Bus
Read model generator
Another context application
Command
Event
Dependency
Domain
Event Store
Read Model Application service
DB Read DB Write
Read Model Application service
DB Read
UI
Command Handler
Command Bus
Event Bus
Read model generator
ACL
Command Handler
Domain RepositoryRead model generator
Command
Event
Dependency
Domain
Event Store
Read Model Application service
UI
Command Handler
Command Bus
Event Bus
Another context application
Command
Event
Dependency
Our system seems to be on the right track now !
Lesson learn 5
Resilient
Easily scalable and
preferment
Decoupled and easy to integrate with external
systems
Domain centric, refactorableand evolvable
Simple architecture, does not scale, hard to maintain, often monolithic
Recipe 1:Basic layered architecture
Recipe 2:n-layered architecture with DI
Recipe 3:Hexagonal with basic CQRS
Recipe 4:Hexagonal’ish with CQRS + DDD
Recipe 5:Hexagonal’ish with CQRS + DDD + ES
Recipe 5
Basic CQRS + DDD + ES
Ingredients
Good OOP skillsSOLID principlesDomain Driven Design modelingGood knowledge of messaging infrastructureFunctional thinking
Client reviews
• Handles concurrent domains• Scale out read from writes independently• Can handle more business request about queries• Business process explicit• Audit log, testing and infinite business views on data
• Many moving parts• Sometimes integration points between systems are harder to grasp• Bad things can happen if no integration events command are stored
Difficulty:
Time: long termPreparation:Make your events talk.
Domain
Event Store
Read Model Application
service
DB Read
DB Write
Read Model Application
service
DB Read
UI
Command Handler
Command Bus
Event Bus
Read model
generator
ACL
Command Handler
DomainRepositor
y
Read model
generator
Maslow architecture pyramidNot official, just my own trip
Resilient
Easily scalable and
preferment
Decoupled and easy to integrate with external
systems
Domain centric, refactorableand evolvable
Simple architecture, does not scale, hard to maintain, often monolithic
Culinary art
Fine food
Home cooking
Fast food and frozen food
Basic ingredients like milk, bread, meat
What CQRS is not?CQRS Basics/From CQS to CQRS
Is CQRS for me?CQRS Basics/From CQS to CQRS
What kind of problem do I try to solve ?
• Collaborative domain• Locking the data without blocking the user
• Read data scalability
• Performance optimization
• Complex workflows / Temporal data / Stale data
There is more
Aggregates
• Validation
• Uniqueness checking
• Existence checking
• Replaying of events (Event Sourced)
Long running workflows
Optimization
Long running workflowsCQRS Deep Dive Cooking
How do I know if I need one?
Difference between Saga and Process Manager?
Client
Order ProcessManager
OrderAggregate
Stock Aggregate
PaymentAggregate
2. O
rder
Pla
ced
3. Make reservation
4. ItemsReserved
5. M
ake
pay
men
t
6. P
aym
entA
ccep
ted
7. OrderConfirmed
7. O
rder
Co
nfi
rmed
7. OrderConfirmed
Questions ?