CQRS recepies
HOW TO BUILD YOUR ARCHITECTURE
Francesco Garavaglia
04/2016
2
About me
 over 10 years of experience in IT consulting companies.
 Took part in large scale projects
 Energy Markets
 Bank
 Insurance
 Pay attention to Software architecture and Business value
 Photographer
 High-Aggressive-I-eat-you-German-Shepherd-Protected-by
 LinkedIn Page:
https://it.linkedin.com/in/francesco-garavaglia-3333653b
About me
Agenda
 The Problem
 The A brief history
 Lesson #1: Basic layered architecture
 Lesson #2: N-layered architecture with DI
 Lesson #3: basic CQRS
 Lesson #4: Basic CQRS + DDD + Async
 Lesson #5: Basic CQRS + DDD + ES
 A final word
3
What problems
are we trying to
solve?
4
Typical ”Fitting-
all” architecture
Client
Remote Facade
Application Service
Data Access Layer
Data Storage
Domain Object
Domain
Object
DTO DTO
Infrastructure(log,security,etc.)
The Problem
6
Typical ”Fitting-all” architecture
 You can find it on microsoft web site: Layered
Application Guidelines:
http://msdn.microsoft.com/en-us/library/ee658109
 If microsoft says «Use it», it’s obviously the best
practice
The Problem
What’s wrong?
7
8
Nothing
Thanks
FRANCESCO.GARAVAGLIA@GMAIL.COM
10
11
Wait,
Breath & re-think
12
Typical ”Fitting-all” architecture
Client
Remote Facade
Application Service
Data Access Layer
Data Storage
Domain
Object
Domain
Object
DTO DTO
Infrastructure(log,security,etc.)
What’s wrong:
 Temporal coupling
 Physical coupling (inteconnected objetcs)
 Scalability not considered at the core of
the design (scalability gets hacked in too
late)
 Mapping DB structures up to UI
The Problem
13
Many perspectives on data
Customer
Online Ordering System
Pricing
Inventory
Sales
Product
Unit Price
Promotional Price
Promotion End Date
Stock Keeping Unit (SKU)
Quantity On Hand (QOH)
Location Code
Price
Quantity Ordered
Name
What about the lifecycles for the data?
The Problem
14
One big model to capture it ALL
….
…..
…..
….
…..
…..
….
…..
…..
….
…..
…..
The Problem
16
My Treasure
ONE MODEL TO RULE THEM ALL
ONE MODEL TO FIND THEM
ONE MODEL TO BRING THEM ALL
AND IN THE DARKNESS BIND THEM
The Problem
17
The database determines our scalability
The Problem
18
And databases often scale poorly
To solve the
performance
problems for a few,
you have to upgrade
it all
The Problem
19
Alternatively we can use Read replicas
Master Slave SlaveSlaveSlave
You’re now eventually consistent
The Problem
20
Or introduce caching…
What’s your synchronization mechanism?
?
The Problem
21
Typical causes:
 Too many layers
 Big data models
 Anemic domain model
 Focus on frameworks instead of
on the domain
 Scalability not considered at the
core of the design (scalability
gets hacked in too late)
Time
Complexity
Complexity of code and solution
The Problem
22
Try new Solution
The Problem
Architecture
Pyramid
23
Skyscraper
Apartment block
Small house
Wood house (tools cot)
Basic ingredients: Bricks,
concrete, woods, etc.
What about
software????
24A brief history
A brief history
A brief history:
Once upon a
time....
25
A brief history
One upon a
time, a
marketing team
came in to
announce to
developers what
they have sold
26
27
A brief story
 We need an e-commerce portal
 We need now
 Do it fast
 We need every features:
 Order
 Product catalog
 Suppliers
 Available for all devices in the world
A brief history
A brief history
Developers
have started
their work....
28
A brief history
Developers
continue their
works....
29
A brief history
After a while...
30
A brief history
E-Commerce
portal
Architecture
User Interface
Domain Logic
Data Access Layer
DB
31
A brief history
But another
feature was
asked by the
business...
32
... And
developers start
to work again...
33A brief history
A brief history
... After one
year...
34
A brief history
The Monolith
appears!
35
36
Lesson #1
Skyscraper
Apartment block
Small house
Wood house (tools cot)
Basic ingredients: Bricks,
concrete, woods, etc.
Simple architecture, does not
scale, hard to maintain, often
monolithic
Recipe 1:
Basic layered
architecture
Recipe 1:
Basic layered architecture
Lesson #1
37
Basic Layered Architecture
Ingredients
Basic coding skills
Some infrastructure pieces (DB,
etc.)
Difficulty:
Time: from 25 min to infinity
Preparation:
Just throw basic code skills in.
Mix it up with a database and UI
and everything will be fine
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
• Low perfomances if charge gets bigger
• Not testable. You’d better have end-to-end integration tests
Lesson #1
Lesson #1
We need a
refactor!!!
38
Lesson #2
How do we
refator a
monolith?
39
Lesson #2
 Decouple every component
 Evolve domain
independently.
 Handle business needs easier
40
Lesson #2
 Decouple every component
 Handle business logic in
isolated domain
 Write unit test because every
change is a breaking one
 We have to think it over, but for
now let’s wrap up what we’ve
learnt
41
42
Decoupling
 Let’s decouple from DB:
 Let’s decouple from everything else
 «Is the best-practice recommended by Microsoft»
Entity Framework
Unity
Lesson #2
Lesson #2
Business asks for
more features
for Orders,
Suppliers, stuff....
43
Lesson #2
We need a
refactor!!!
44
Lesson #2
Add more
Layers!!!!
45
46
Decoupling (2)
Lesson #2
47
Layered Architecture v.2
UI
OrderViewModel
Order
OrderController
OrderMapper IOrderMapper
SqlOrderRepository IOrderRepository
DB
PresentationDomainInfrastructure
public class OrderController
{
public OrderController (
IOrderValidator order validator,
IOrderMapper orderMapper,
IOrderRepository orderRepository
ISupplierRepository supplierRepository
IAuthorizationFactory authorizationFactory,
IUnitOfWork unitOfWork,
IUserFactory userFactory
ISession session,
ILogger logger,
IOrderCache orderCache)
{
}
}
Lesson #2
Lesson #2
We need more
data on UI and
different views
per user or
device...
48
49
But...
 But our model doesn’t support it
 Every time we add a new view
our model is broken…
 Views are slower. Users
complain…
Lesson #2
50
Lesson #2
Skyscraper
Apartment block
Small house
Wood house (tools cot)
Basic ingredients: Bricks,
concrete, woods, etc.
Simple architecture, does not scale, hard to maintain,
often monolithic
Recipe 1:
Basic layered
architecture
Recipe 2:
n-layered architecture with DI
Domain centric, refactorable
and evolvable
Lesson #2
51
N-Layered architecture with DI
Ingredients
OOP skills
With SOLID principles would
be event better
ORMs and IOCs
Some infrastructure pieces
(DB, etc.)
Difficulty:
Time: Reasonable
Preparation:
One must know OOP
concepts and the best would
be also to be aware of SOLID
principles…
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
• Low perfomances if charge gets bigger
Lesson #2
Lesson #3
 Read and Write from
separate logics
 CQRS
53
Lesson #3
CQRS?
54
55
What the hell is CQRS?
 “Segregate operations that read data from operations that update data by using separate
interfaces. This pattern can maximize performance, scalability, and security; support evolution of
the system over time through higher flexibility; and prevent update commands from causing
merge conflicts at the domain level.”
 Not a framework
 Not an architecture
 Not a specific tool
 Not a BEST PRACTICE
 I always start the CQRS conversation with “THIS IS LIKELY NOT FOR YOU”
 CQRS is great when it is justifiably needed
 Due to high complexity, not a buzz word you want “just cause”
Lesson #3
56
What the hell is CQRS?
 CQS (Command Query Separation) applied to Architecture
 Split Read from Write stuff
 CQRS ends up being a composition of tools and concepts
 No two CQRS implementations are identical
Users decide actions
according to the real world
experience (things they know
which are not in the system)
and read Model
Humans decide according
to different sets of info (ex:
faces, pictures, surnames,
ecc)
CQS: Command Query Separation
• Command methods change state
• Query methods read state
• One object in code for state change and
querying works
• Using the same data store is ok
• Supports shared schema with read replica
concepts
Lesson #3
57
What is CQRS?
 CQRS: Command & Query Responsibility Segregation
“Two objects where there once was one”
 Command objects change state
 Query objects read state
 Two objects represented in code
 One for state change
 One for querying data
 Decoupled model for different concerns
Lesson #3
public class UserWriteService
{
// Commands
public void Move(User user, string newAddress);
//...
}
public class UserReadService
{
// Queries
public User GetUser(int userId);
//...
}
58
Segregation opens doors
 Scale reads from writes independently
 Remove contention
 Decouple read model from write model
 Different data shapes
 Flexibility in modeling different concerns
 Ability to capture with why the state changed
 Not just changing the state
Lesson #3
59
CQRS: Command
 Message
 Handler changes state
 Always returns void (nothing)
 Commands encapsulate the user’s intent
but do not contain business logic,
 Not a CRUD style operation
Lesson #3
public class MoveCustomerCommand : Command
{
public Address NewAddress { get; set; }
}
public class CustomerHandler
IHandleMessage<MoveCustomerCommand>
{
public void Handle(MoveCustomerCommand cmd)
{ …. }
}
60
CQRS: Query
 Does not change state
 Has return value
 Also a type of message
Lesson #3
61
CQS vs. CQRS: Feature matrix
CQS CQRS
Zero coupling between domain logic (state) and reporting (read)
concerns
X
More robust scalability options X
Decouples domain concerns from display concerns X
Object model specific to its responsibility X
Different data stores/shapes for domain logic and reporting concerns X
Option to performance optimize data storage for write and read layer(s) X X
Can be used with a message based architecture X X
Easy deployment story X
Less code complexity X
Less pieces to manage X
Coupled read and write model X
Lesson #3
62
How does CQRS work?
Lesson #3
Create Order
Change Address
CommandBus
Command
captures the
intent of the user
After database is
updated, publish
result to view
model
Query
Event Bus
A queue can be
utilized to
optimize write
performance
Scale out as many
copies as needed
Persistent View Model
schema matches UI
view model
Domain
Handles
Commands
63
CQRS in code
 Abstract interfaces for Command and Query
public interface ICommand { }
public interface ICommandHandler<in TCommand> where TCommand : ICommand
{
void Execute(TCommand command);
}
public interface ICommandDispatcher
{
void Execute<TCommand>(TCommand command) where TCommand : ICommand;
}
public interface IQuery<TResult> { }
public interface IQueryHandler<in TQuery, out TResult>
where TQuery : IQuery<TResult>
{
TResult Execute(TQuery query);
}
public interface IQueryDispatcher
{
TResult Execute<TQuery, TResult>(TQuery query)
where TQuery : IQuery<TResult>;
}
public class CommandDispatcher : ICommandDispatcher
{
private readonly IDependencyResolver _resolver;
public CommandDispatcher(IDependencyResolver resolver)
{ _resolver = resolver; }
public void Execute<TCommand>(TCommand command)
where TCommand : ICommand
{
if(command == null) { throw new ArgumentNullException("command"); }
var handler = _resolver.Resolve<ICommandHandler<TCommand>>();
if (handler == null)
{ throw new CommandHandlerNotFoundException(typeof(TCommand)); }
handler.Execute(command);
}
}
Lesson #3
64
CQRS in code
 Implementation for SignOn:
public class SignOnCommand : ICommand
{
public AssignmentId Id { get; private set; }
public LocalDateTime EffectiveDate { get; private set; }
public SignOnCommand(AssignmentId assignmentId, LocalDateTime effectiveDate)
{
Id = assignmentId; EffectiveDate = effectiveDate;
}
}
 To execute:
_commandDispatcher.Execute(new SignOnCommand(new AssignmentId(rawId), effectiveDate));
public class SignOnCommandHandler : ICommandHandler<SignOnCommand>
{
private readonly AssignmentRepository _assignmentRepository;
private readonly SignOnPolicyFactory _factory;
public SignOnCommandHandler(AssignmentRepository assignmentRepository,
SignOnPolicyFactory factory)
{
_assignmentRepository = assignmentRepository;
_factory = factory;
}
public void Execute(SignOnCommand command)
{
var assignment = _assignmentRepository.GetById(command.Id);
if (assignment == null)
{ throw new MeaningfulDomainException("Assignment not found!"); }
var policy = _factory.GetPolicy();
assignment.SignOn(command.EffectiveDate, policy);
}
}
Lesson #3
65
CQRS in code
 Query Dispatcher:
public class QueryDispatcher : IQueryDispatcher
{
private readonly IDependencyResolver _resolver;
public QueryDispatcher(IDependencyResolver resolver) { _resolver = resolver; }
public TResult Execute<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult>
{
if (query == null) { throw new ArgumentNullException("query"); }
var handler = _resolver.Resolve<IQueryHandler<TQuery, TResult>>();
if (handler == null) { throw new QueryHandlerNotFoundException(typeof(TQuery)); }
return handler.Execute(query);
}
}
Lesson #3
66
CQRS in code
 Adding more pseudo-aspects:
public class TransactionalCommandDispatcher : ICommandDispatcher
{
private readonly ICommandDispatcher _next;
private readonly ISessionFactory _sessionFactory;
public TransactionalCommandDispatcher(ICommandDispatcher next, ISessionFactory sessionFactory)
{
_next = next;
_sessionFactory = sessionFactory;
}
public void Execute<TCommand>(TCommand command) where TCommand : ICommand
{
using (var session = _sessionFactory.GetSession())
using (var tx = session.BeginTransaction())
{
try { _next.Execute(command); tx.Commit(); }
catch { tx.Rollback(); throw; }
}
}
}
Lesson #3
67
Architecture v3
Lesson #3
Lesson #3
 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
68
Lesson #3
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.
69
70
Lesson #3
Skyscraper
Apartment block
Small house
Wood house (tools cot)
Basic ingredients: Bricks,
concrete, woods, etc.
Simple architecture, does not scale, hard to maintain,
often monolithic
Recipe 1:
Basic layered
architecture
Recipe 3:
Hexagonal with basic CQRS
Decoupled and easy to integrate with external
systems
Domain centric, refactorable and evolable
Recipe 2: N-
layered
architecture with DI
Lesson #3
71
Basic CQRS
Ingredients
OOP skills
SOLID principles
Domain Driven Design would
be a big advantage
Difficulty:
Time: Mid Term
Preparation:
Establish a ubiquitous
language with your domain
experts and express it in the
code
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
Lesson #3
Lesson #4
Where do we
put the major
effort?
72
What is the strategic
advantage for the
company?
73Lesson #4
But how do we find
the best model for a
business…
74Lesson #4
Lesson #4
 Ask to the Business
75
Lesson #4
 Event Storming = Domain
Discovery tool of the
business
76
77
Event Storming
 Event Storming is a fun way of bringing developers and business experts together and drive your
analysis from the outside and quickly explore complex business domains in hours instead of
days/weeks.
Event Storming (or Model storming) is a way of
starting your analysis from the outside and quickly
explore complex business domains.
Invented by Alberto Brandolini
See
http://ziobrando.blogspot.dk/2013/11/introducing-
event-storming.html
Lesson #4
Lesson #4
Finally, Events!
We think only about
them!
78
Lesson #4
 One Event, One handler: the
aggregates
 Event + Aggregates = DDD
79
80
Domain Driven Design
 I’s not a technology or a metodology: I’s a set o principles and patterns for focusing design effort
where it matter most.
 It’s much more than events
 Ubiquitous language
 Bounded Context
 Context map
 Model
 Domain event
 Aggregates
Application
Bounded
Context
Business
Compon
ent
Autonomous
Business
Component
Lesson #4
81
Domain Driven Design
 Domain:
 A Domain is a Sphere of Knowledge, Influence or Activity
 A Domain is represented by the Ubiquitous Language
 A Domain encapsulates a Domain Model
 A Domain lives within a Bounded Context
 Ubiquitous language
 A major reason for failure of software projects is a failure of people, the failure to communicate
 The Ubiquitous Language is a shared language between the business and the development teams
 The UL comes from the business, and is enriched by the development teams
 Domain Experts
 Domain Experts are the primary point of contact the development teams have with the business
 They are the Experts on their part of the business, not just users of the system
 They should have deep knowledge of the subject Domain
Lesson #4
82
Domain Driven Design
 Entities:
 Entities are the “things” within your Model
 An Entity is defined by being unique, and uniquely identifiable
 Value Objects:
 Value Objects are the “things” within your model that have no uniqueness
 They are equal in all ways to another Value Object if all their properties match
 Value Objects are interchangeable
 Domain Model:
 A Domain Model is a representation of the relationships between the Entities and Value Objects in your
Domain
 It may look similar to UML or a class relationship diagram, but it is not one  SEVERAL MODELS!!!!
 The Domain Model should be recognisable and understandable by the business
Lesson #4
83
Domain Driven Design
 Aggregates:
 “An aggregate is a collection of items that are gathered together to form a total quantity” - Wikipedia
 An Aggregate Root is the root item containing a number of parts that form a whole
 An AR is more likely to match a Use Case than any model structure
 Bounded Contexts
 When you have multiple models you should consider Bounded Contexts
 Each BC is a self contained “mini application” containing it’s own model, persistence and code base
 To map between BCs you use a Context Map
 Anti-Corruption Layer
 An Anti-Corruption Layer is a method to isolate two systems, allowing systems to be integrated without
knowledge of each other
 An ACL presents a Facade to both systems, defined in terms of their specific models
 ACLs maintain the integrity of a Domain
Lesson #4
84
Domain Driven Design
 Events:
 describe changes in the system state
 An Event Bus can be utilized to dispatch events to subscribers
 Events primary purpose update the read model
 Events can also provider integration with external systems
 CQRS can also be used in conjunction with Event Sourcing.
Event Sourcing
Captures all changes to an application state as a sequence of events. The current state is
constructed by applying the events in the order they were recorded. Not only does it give us the
current state, but we can also use the event log to reconstruct past states, and as a foundation to
automatically adjust the state to cope with retroactive changes.
Summarized from Martin Fowler – http://martinfowler.com/eaaDev/EventSourcing.html
Lesson #4
85
Hexagonal architecture or Port and Adapter
 Ports are API or contracts in and out of the domain
 Adapters translate between Ports and external dependencies
 Swap out external dependencies implementation using different adapters or using mocks
Domai
n
UI
API
Data Store
External
Services
Ports
Adapters
Lesson #4
86
The Domain at the center of everything
 Push everything to the sides and concentrate on the middle
 For big app components => Hexagonal architecture to split into smaller chunk
 Either monolithic app or micro-services
Lesson #4
Lesson #4
We need a new
feature: concert
ticket sell
87
Lesson #4
 Done
88
Lesson #4
System is unusable:
users are blocked
89
Lesson #4
WTF…
90
91
Lesson #4
 Express business intent in
commands and facts in
events
 Command, it’s business
intent like “Place Order”
 Event, it’s business
immutable fact like
“OrderPlaced”
 Make events asynchronous
92
93
Different architectures
Composite UI
UI
Data Access Layer
Web /
Application
Tier
Background
server Tier
Storage Tier
DDD layered
application
Write
model
Read
model
Legacy
application
Domain A Domain B Domain C Domain D
CRUD architecture
(simple non-core
domain functionality)
DDD (core domain
functionality)
CQRS (core domain
functionality)
Legacy subsystem
Lesson #4
94
Domain Repository
DB Write
Read Model Application service
DB Read
UI
Command Handler
Event Bus
Read model
generator
Another context application
Command
Event
Dependency
Architecture v4
Lesson #4
Command Bus
95
Domain Repository
DB Write
Read Model Application service
DB Read DB Write
Read ModelApplication service
DB Read
Command Handler
Command Bus
Event Bus
Read model
generator
ACL
Command Handler
Domain Repository
Read model
generator
UI
Command
Event
Dependency
Architecture v4.1
Lesson #4
96
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.2
Lesson #4
Lesson #4
There is a trap
 Views are not refreshed
immediately
 Event syncronization
97
Lesson #4 98
There is a trap
 event synchronization
99
Write side Read side
UI
Write Model
DB Write
Read Model
DB Read
Update write side
data store Update read side
data store
Read data
Transaction Scope
Event synchronization
Lesson #4
100
Write side Read side
UI
Write Model
DB Write
Read Model
DB Read
Update write side
data store
Send message to
update read side
data store
Read data
Transaction Scope
Event Bus
Reliable messaging
Event synchronization 2
Lesson #4
Lesson #4
I would like to know if
user before placing an
Order removes Items if
we propose them more
useful articles with our
recommendation
system
101
102
But...
 We don’t have a History
Lesson #4
So?
What’s Next
move?
103
105
Lesson #4
Skyscraper
Apartment block
Small house
Wood house (tools cot)
Basic ingredients: Bricks,
concrete, woods, etc.
Simple architecture, does not scale, hard to maintain,
often monolithic
Recipe 1:
Basic layered
architecture
Receipe 4: Hexagonal with CQRS + DDD
Easily scalable and high performances
Domain centric, refactorable and evolable
Recipe 2: N-
layered
architecture with DI
Decoupled and easy to integrate with external systems
Receipe 3:
Hexagonal with
basic CQRS
Lesson #4
106
Basic CQRS + DDD + Async
Ingredients
Good OOP skills
SOLID principles
Domain Driven Design
modeling
Good knowledge of
messaging infrastructure
Difficulty:
Time: Long Term
Preparation:
Gather business intent in form
of Commands, map it to
business events and
synchronize everything async
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
Domain
Repositor
y
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
Repositor
y
Lesson #4
Lesson #5
 All you need to do is using
your events
10
7
Lesson #5
But for legal thing, we
would like an audit log
system
10
8
Lesson #5
We need a time
machine…
10
9
110
Order Order 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
 Event as a storage mechanism
Lesson #5
111
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
Event Sourcing: Rolling snapshot
Lesson #5
112
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
Architecture v5
Lesson #5
113
Domain
Event Store
Read Model Application service
DB Read DB Write
Read ModelApplication service
DB Read
UI
Command Handler
Command Bus
Event Bus
Read model
generator
ACL
Command Handler
Domain Repository
Read model
generator
Command Event Dependency
Architecture v5.1
Lesson #5
114
Domain
Event Store
Read Model Application service
UI
Command Handler
Command Bus
Event Bus
Another context application
Command Event Dependency
Event Sourcing
Lesson #5
Lesson #5
Our system seems to be
on the right track now!!
115
116
Lesson #5
Skyscraper
Apartment block
Small house
Wood house (tools cot)
Basic ingredients: Bricks,
concrete, woods, etc.
Simple architecture, does not scale, hard to maintain,
often monolithic
Recipe 1:
Basic layered
architecture
Domain centric, refactorable and evolable
Recipe 2: N-
layered
architecture with DI
Decoupled and easy to integrate with external systems
Receipe 3:
Hexagonal with
basic CQRS
Easily scalable and high performances
Receipe 4:
Heagonal with
CQRS + DDD
Robust and resilient
Receipe 5:
Heagonal with
CQRS + DDD + ES
Lesson #5
117
Basic CQRS + DDD + ES
Ingredients
Good OOP skills
SOLID principles
Domain Driven Design modeling
Good knowledge of messaging
infrastructure
Functional thinking
Difficulty:
Time: Long Term
Preparation:
Make your events talk
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
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 Repository
Read
model
generator
Lesson #5
THIS IS CQRS
119
What CQRS is not?
A final word
120
Is CQRS for me?
 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
A final word
121
It’s only the beginning of journey
 Aggregates
 Uniqueness checking
 Existence checking
 Replaying of events (Event Sourced)
 Long running workflows
A final word
122
Referencials
 Greg Young’s Simplest Solution: https://github.com/gregoryyoung/m-r
 Simple CQRS demo approach: https://www.youtube.com/watch?v=tTbHR5KScEE
 Fowler’s book
 DDD book by Eric Evans [Blue Book]
 DDD book by Vernon [Red Book]
A final word
Thanks
FRANCESCO.GARAVAGLIA@GMAIL.COM

CQRS recepies

  • 1.
    CQRS recepies HOW TOBUILD YOUR ARCHITECTURE Francesco Garavaglia 04/2016
  • 2.
    2 About me  over10 years of experience in IT consulting companies.  Took part in large scale projects  Energy Markets  Bank  Insurance  Pay attention to Software architecture and Business value  Photographer  High-Aggressive-I-eat-you-German-Shepherd-Protected-by  LinkedIn Page: https://it.linkedin.com/in/francesco-garavaglia-3333653b About me
  • 3.
    Agenda  The Problem The A brief history  Lesson #1: Basic layered architecture  Lesson #2: N-layered architecture with DI  Lesson #3: basic CQRS  Lesson #4: Basic CQRS + DDD + Async  Lesson #5: Basic CQRS + DDD + ES  A final word 3
  • 4.
    What problems are wetrying to solve? 4
  • 5.
    Typical ”Fitting- all” architecture Client RemoteFacade Application Service Data Access Layer Data Storage Domain Object Domain Object DTO DTO Infrastructure(log,security,etc.) The Problem
  • 6.
    6 Typical ”Fitting-all” architecture You can find it on microsoft web site: Layered Application Guidelines: http://msdn.microsoft.com/en-us/library/ee658109  If microsoft says «Use it», it’s obviously the best practice The Problem
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
    12 Typical ”Fitting-all” architecture Client RemoteFacade Application Service Data Access Layer Data Storage Domain Object Domain Object DTO DTO Infrastructure(log,security,etc.) What’s wrong:  Temporal coupling  Physical coupling (inteconnected objetcs)  Scalability not considered at the core of the design (scalability gets hacked in too late)  Mapping DB structures up to UI The Problem
  • 13.
    13 Many perspectives ondata Customer Online Ordering System Pricing Inventory Sales Product Unit Price Promotional Price Promotion End Date Stock Keeping Unit (SKU) Quantity On Hand (QOH) Location Code Price Quantity Ordered Name What about the lifecycles for the data? The Problem
  • 14.
    14 One big modelto capture it ALL …. ….. ….. …. ….. ….. …. ….. ….. …. ….. ….. The Problem
  • 16.
    16 My Treasure ONE MODELTO RULE THEM ALL ONE MODEL TO FIND THEM ONE MODEL TO BRING THEM ALL AND IN THE DARKNESS BIND THEM The Problem
  • 17.
    17 The database determinesour scalability The Problem
  • 18.
    18 And databases oftenscale poorly To solve the performance problems for a few, you have to upgrade it all The Problem
  • 19.
    19 Alternatively we canuse Read replicas Master Slave SlaveSlaveSlave You’re now eventually consistent The Problem
  • 20.
    20 Or introduce caching… What’syour synchronization mechanism? ? The Problem
  • 21.
    21 Typical causes:  Toomany layers  Big data models  Anemic domain model  Focus on frameworks instead of on the domain  Scalability not considered at the core of the design (scalability gets hacked in too late) Time Complexity Complexity of code and solution The Problem
  • 22.
  • 23.
    Architecture Pyramid 23 Skyscraper Apartment block Small house Woodhouse (tools cot) Basic ingredients: Bricks, concrete, woods, etc.
  • 24.
  • 25.
    A brief history Abrief history: Once upon a time.... 25
  • 26.
    A brief history Oneupon a time, a marketing team came in to announce to developers what they have sold 26
  • 27.
    27 A brief story We need an e-commerce portal  We need now  Do it fast  We need every features:  Order  Product catalog  Suppliers  Available for all devices in the world A brief history
  • 28.
    A brief history Developers havestarted their work.... 28
  • 29.
  • 30.
    A brief history Aftera while... 30
  • 31.
    A brief history E-Commerce portal Architecture UserInterface Domain Logic Data Access Layer DB 31
  • 32.
    A brief history Butanother feature was asked by the business... 32
  • 33.
    ... And developers start towork again... 33A brief history
  • 34.
    A brief history ...After one year... 34
  • 35.
    A brief history TheMonolith appears! 35
  • 36.
    36 Lesson #1 Skyscraper Apartment block Smallhouse Wood house (tools cot) Basic ingredients: Bricks, concrete, woods, etc. Simple architecture, does not scale, hard to maintain, often monolithic Recipe 1: Basic layered architecture Recipe 1: Basic layered architecture Lesson #1
  • 37.
    37 Basic Layered Architecture Ingredients Basiccoding skills Some infrastructure pieces (DB, etc.) Difficulty: Time: from 25 min to infinity Preparation: Just throw basic code skills in. Mix it up with a database and UI and everything will be fine 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 • Low perfomances if charge gets bigger • Not testable. You’d better have end-to-end integration tests Lesson #1
  • 38.
    Lesson #1 We needa refactor!!! 38
  • 39.
    Lesson #2 How dowe refator a monolith? 39
  • 40.
    Lesson #2  Decoupleevery component  Evolve domain independently.  Handle business needs easier 40
  • 41.
    Lesson #2  Decoupleevery component  Handle business logic in isolated domain  Write unit test because every change is a breaking one  We have to think it over, but for now let’s wrap up what we’ve learnt 41
  • 42.
    42 Decoupling  Let’s decouplefrom DB:  Let’s decouple from everything else  «Is the best-practice recommended by Microsoft» Entity Framework Unity Lesson #2
  • 43.
    Lesson #2 Business asksfor more features for Orders, Suppliers, stuff.... 43
  • 44.
    Lesson #2 We needa refactor!!! 44
  • 45.
  • 46.
  • 47.
    47 Layered Architecture v.2 UI OrderViewModel Order OrderController OrderMapperIOrderMapper SqlOrderRepository IOrderRepository DB PresentationDomainInfrastructure public class OrderController { public OrderController ( IOrderValidator order validator, IOrderMapper orderMapper, IOrderRepository orderRepository ISupplierRepository supplierRepository IAuthorizationFactory authorizationFactory, IUnitOfWork unitOfWork, IUserFactory userFactory ISession session, ILogger logger, IOrderCache orderCache) { } } Lesson #2
  • 48.
    Lesson #2 We needmore data on UI and different views per user or device... 48
  • 49.
    49 But...  But ourmodel doesn’t support it  Every time we add a new view our model is broken…  Views are slower. Users complain… Lesson #2
  • 50.
    50 Lesson #2 Skyscraper Apartment block Smallhouse Wood house (tools cot) Basic ingredients: Bricks, concrete, woods, etc. Simple architecture, does not scale, hard to maintain, often monolithic Recipe 1: Basic layered architecture Recipe 2: n-layered architecture with DI Domain centric, refactorable and evolvable Lesson #2
  • 51.
    51 N-Layered architecture withDI Ingredients OOP skills With SOLID principles would be event better ORMs and IOCs Some infrastructure pieces (DB, etc.) Difficulty: Time: Reasonable Preparation: One must know OOP concepts and the best would be also to be aware of SOLID principles… 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 • Low perfomances if charge gets bigger Lesson #2
  • 53.
    Lesson #3  Readand Write from separate logics  CQRS 53
  • 54.
  • 55.
    55 What the hellis CQRS?  “Segregate operations that read data from operations that update data by using separate interfaces. This pattern can maximize performance, scalability, and security; support evolution of the system over time through higher flexibility; and prevent update commands from causing merge conflicts at the domain level.”  Not a framework  Not an architecture  Not a specific tool  Not a BEST PRACTICE  I always start the CQRS conversation with “THIS IS LIKELY NOT FOR YOU”  CQRS is great when it is justifiably needed  Due to high complexity, not a buzz word you want “just cause” Lesson #3
  • 56.
    56 What the hellis CQRS?  CQS (Command Query Separation) applied to Architecture  Split Read from Write stuff  CQRS ends up being a composition of tools and concepts  No two CQRS implementations are identical Users decide actions according to the real world experience (things they know which are not in the system) and read Model Humans decide according to different sets of info (ex: faces, pictures, surnames, ecc) CQS: Command Query Separation • Command methods change state • Query methods read state • One object in code for state change and querying works • Using the same data store is ok • Supports shared schema with read replica concepts Lesson #3
  • 57.
    57 What is CQRS? CQRS: Command & Query Responsibility Segregation “Two objects where there once was one”  Command objects change state  Query objects read state  Two objects represented in code  One for state change  One for querying data  Decoupled model for different concerns Lesson #3 public class UserWriteService { // Commands public void Move(User user, string newAddress); //... } public class UserReadService { // Queries public User GetUser(int userId); //... }
  • 58.
    58 Segregation opens doors Scale reads from writes independently  Remove contention  Decouple read model from write model  Different data shapes  Flexibility in modeling different concerns  Ability to capture with why the state changed  Not just changing the state Lesson #3
  • 59.
    59 CQRS: Command  Message Handler changes state  Always returns void (nothing)  Commands encapsulate the user’s intent but do not contain business logic,  Not a CRUD style operation Lesson #3 public class MoveCustomerCommand : Command { public Address NewAddress { get; set; } } public class CustomerHandler IHandleMessage<MoveCustomerCommand> { public void Handle(MoveCustomerCommand cmd) { …. } }
  • 60.
    60 CQRS: Query  Doesnot change state  Has return value  Also a type of message Lesson #3
  • 61.
    61 CQS vs. CQRS:Feature matrix CQS CQRS Zero coupling between domain logic (state) and reporting (read) concerns X More robust scalability options X Decouples domain concerns from display concerns X Object model specific to its responsibility X Different data stores/shapes for domain logic and reporting concerns X Option to performance optimize data storage for write and read layer(s) X X Can be used with a message based architecture X X Easy deployment story X Less code complexity X Less pieces to manage X Coupled read and write model X Lesson #3
  • 62.
    62 How does CQRSwork? Lesson #3 Create Order Change Address CommandBus Command captures the intent of the user After database is updated, publish result to view model Query Event Bus A queue can be utilized to optimize write performance Scale out as many copies as needed Persistent View Model schema matches UI view model Domain Handles Commands
  • 63.
    63 CQRS in code Abstract interfaces for Command and Query public interface ICommand { } public interface ICommandHandler<in TCommand> where TCommand : ICommand { void Execute(TCommand command); } public interface ICommandDispatcher { void Execute<TCommand>(TCommand command) where TCommand : ICommand; } public interface IQuery<TResult> { } public interface IQueryHandler<in TQuery, out TResult> where TQuery : IQuery<TResult> { TResult Execute(TQuery query); } public interface IQueryDispatcher { TResult Execute<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult>; } public class CommandDispatcher : ICommandDispatcher { private readonly IDependencyResolver _resolver; public CommandDispatcher(IDependencyResolver resolver) { _resolver = resolver; } public void Execute<TCommand>(TCommand command) where TCommand : ICommand { if(command == null) { throw new ArgumentNullException("command"); } var handler = _resolver.Resolve<ICommandHandler<TCommand>>(); if (handler == null) { throw new CommandHandlerNotFoundException(typeof(TCommand)); } handler.Execute(command); } } Lesson #3
  • 64.
    64 CQRS in code Implementation for SignOn: public class SignOnCommand : ICommand { public AssignmentId Id { get; private set; } public LocalDateTime EffectiveDate { get; private set; } public SignOnCommand(AssignmentId assignmentId, LocalDateTime effectiveDate) { Id = assignmentId; EffectiveDate = effectiveDate; } }  To execute: _commandDispatcher.Execute(new SignOnCommand(new AssignmentId(rawId), effectiveDate)); public class SignOnCommandHandler : ICommandHandler<SignOnCommand> { private readonly AssignmentRepository _assignmentRepository; private readonly SignOnPolicyFactory _factory; public SignOnCommandHandler(AssignmentRepository assignmentRepository, SignOnPolicyFactory factory) { _assignmentRepository = assignmentRepository; _factory = factory; } public void Execute(SignOnCommand command) { var assignment = _assignmentRepository.GetById(command.Id); if (assignment == null) { throw new MeaningfulDomainException("Assignment not found!"); } var policy = _factory.GetPolicy(); assignment.SignOn(command.EffectiveDate, policy); } } Lesson #3
  • 65.
    65 CQRS in code Query Dispatcher: public class QueryDispatcher : IQueryDispatcher { private readonly IDependencyResolver _resolver; public QueryDispatcher(IDependencyResolver resolver) { _resolver = resolver; } public TResult Execute<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult> { if (query == null) { throw new ArgumentNullException("query"); } var handler = _resolver.Resolve<IQueryHandler<TQuery, TResult>>(); if (handler == null) { throw new QueryHandlerNotFoundException(typeof(TQuery)); } return handler.Execute(query); } } Lesson #3
  • 66.
    66 CQRS in code Adding more pseudo-aspects: public class TransactionalCommandDispatcher : ICommandDispatcher { private readonly ICommandDispatcher _next; private readonly ISessionFactory _sessionFactory; public TransactionalCommandDispatcher(ICommandDispatcher next, ISessionFactory sessionFactory) { _next = next; _sessionFactory = sessionFactory; } public void Execute<TCommand>(TCommand command) where TCommand : ICommand { using (var session = _sessionFactory.GetSession()) using (var tx = session.BeginTransaction()) { try { _next.Execute(command); tx.Commit(); } catch { tx.Rollback(); throw; } } } } Lesson #3
  • 67.
  • 68.
    Lesson #3  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 68
  • 69.
    Lesson #3 Even ofit’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. 69
  • 70.
    70 Lesson #3 Skyscraper Apartment block Smallhouse Wood house (tools cot) Basic ingredients: Bricks, concrete, woods, etc. Simple architecture, does not scale, hard to maintain, often monolithic Recipe 1: Basic layered architecture Recipe 3: Hexagonal with basic CQRS Decoupled and easy to integrate with external systems Domain centric, refactorable and evolable Recipe 2: N- layered architecture with DI Lesson #3
  • 71.
    71 Basic CQRS Ingredients OOP skills SOLIDprinciples Domain Driven Design would be a big advantage Difficulty: Time: Mid Term Preparation: Establish a ubiquitous language with your domain experts and express it in the code 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 Lesson #3
  • 72.
    Lesson #4 Where dowe put the major effort? 72
  • 73.
    What is thestrategic advantage for the company? 73Lesson #4
  • 74.
    But how dowe find the best model for a business… 74Lesson #4
  • 75.
    Lesson #4  Askto the Business 75
  • 76.
    Lesson #4  EventStorming = Domain Discovery tool of the business 76
  • 77.
    77 Event Storming  EventStorming is a fun way of bringing developers and business experts together and drive your analysis from the outside and quickly explore complex business domains in hours instead of days/weeks. Event Storming (or Model storming) is a way of starting your analysis from the outside and quickly explore complex business domains. Invented by Alberto Brandolini See http://ziobrando.blogspot.dk/2013/11/introducing- event-storming.html Lesson #4
  • 78.
    Lesson #4 Finally, Events! Wethink only about them! 78
  • 79.
    Lesson #4  OneEvent, One handler: the aggregates  Event + Aggregates = DDD 79
  • 80.
    80 Domain Driven Design I’s not a technology or a metodology: I’s a set o principles and patterns for focusing design effort where it matter most.  It’s much more than events  Ubiquitous language  Bounded Context  Context map  Model  Domain event  Aggregates Application Bounded Context Business Compon ent Autonomous Business Component Lesson #4
  • 81.
    81 Domain Driven Design Domain:  A Domain is a Sphere of Knowledge, Influence or Activity  A Domain is represented by the Ubiquitous Language  A Domain encapsulates a Domain Model  A Domain lives within a Bounded Context  Ubiquitous language  A major reason for failure of software projects is a failure of people, the failure to communicate  The Ubiquitous Language is a shared language between the business and the development teams  The UL comes from the business, and is enriched by the development teams  Domain Experts  Domain Experts are the primary point of contact the development teams have with the business  They are the Experts on their part of the business, not just users of the system  They should have deep knowledge of the subject Domain Lesson #4
  • 82.
    82 Domain Driven Design Entities:  Entities are the “things” within your Model  An Entity is defined by being unique, and uniquely identifiable  Value Objects:  Value Objects are the “things” within your model that have no uniqueness  They are equal in all ways to another Value Object if all their properties match  Value Objects are interchangeable  Domain Model:  A Domain Model is a representation of the relationships between the Entities and Value Objects in your Domain  It may look similar to UML or a class relationship diagram, but it is not one  SEVERAL MODELS!!!!  The Domain Model should be recognisable and understandable by the business Lesson #4
  • 83.
    83 Domain Driven Design Aggregates:  “An aggregate is a collection of items that are gathered together to form a total quantity” - Wikipedia  An Aggregate Root is the root item containing a number of parts that form a whole  An AR is more likely to match a Use Case than any model structure  Bounded Contexts  When you have multiple models you should consider Bounded Contexts  Each BC is a self contained “mini application” containing it’s own model, persistence and code base  To map between BCs you use a Context Map  Anti-Corruption Layer  An Anti-Corruption Layer is a method to isolate two systems, allowing systems to be integrated without knowledge of each other  An ACL presents a Facade to both systems, defined in terms of their specific models  ACLs maintain the integrity of a Domain Lesson #4
  • 84.
    84 Domain Driven Design Events:  describe changes in the system state  An Event Bus can be utilized to dispatch events to subscribers  Events primary purpose update the read model  Events can also provider integration with external systems  CQRS can also be used in conjunction with Event Sourcing. Event Sourcing Captures all changes to an application state as a sequence of events. The current state is constructed by applying the events in the order they were recorded. Not only does it give us the current state, but we can also use the event log to reconstruct past states, and as a foundation to automatically adjust the state to cope with retroactive changes. Summarized from Martin Fowler – http://martinfowler.com/eaaDev/EventSourcing.html Lesson #4
  • 85.
    85 Hexagonal architecture orPort and Adapter  Ports are API or contracts in and out of the domain  Adapters translate between Ports and external dependencies  Swap out external dependencies implementation using different adapters or using mocks Domai n UI API Data Store External Services Ports Adapters Lesson #4
  • 86.
    86 The Domain atthe center of everything  Push everything to the sides and concentrate on the middle  For big app components => Hexagonal architecture to split into smaller chunk  Either monolithic app or micro-services Lesson #4
  • 87.
    Lesson #4 We needa new feature: concert ticket sell 87
  • 88.
  • 89.
    Lesson #4 System isunusable: users are blocked 89
  • 90.
  • 91.
  • 92.
    Lesson #4  Expressbusiness intent in commands and facts in events  Command, it’s business intent like “Place Order”  Event, it’s business immutable fact like “OrderPlaced”  Make events asynchronous 92
  • 93.
    93 Different architectures Composite UI UI DataAccess Layer Web / Application Tier Background server Tier Storage Tier DDD layered application Write model Read model Legacy application Domain A Domain B Domain C Domain D CRUD architecture (simple non-core domain functionality) DDD (core domain functionality) CQRS (core domain functionality) Legacy subsystem Lesson #4
  • 94.
    94 Domain Repository DB Write ReadModel Application service DB Read UI Command Handler Event Bus Read model generator Another context application Command Event Dependency Architecture v4 Lesson #4 Command Bus
  • 95.
    95 Domain Repository DB Write ReadModel Application service DB Read DB Write Read ModelApplication service DB Read Command Handler Command Bus Event Bus Read model generator ACL Command Handler Domain Repository Read model generator UI Command Event Dependency Architecture v4.1 Lesson #4
  • 96.
    96 Domain Repository DB Write ReadModel 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.2 Lesson #4
  • 97.
    Lesson #4 There isa trap  Views are not refreshed immediately  Event syncronization 97
  • 98.
    Lesson #4 98 Thereis a trap  event synchronization
  • 99.
    99 Write side Readside UI Write Model DB Write Read Model DB Read Update write side data store Update read side data store Read data Transaction Scope Event synchronization Lesson #4
  • 100.
    100 Write side Readside UI Write Model DB Write Read Model DB Read Update write side data store Send message to update read side data store Read data Transaction Scope Event Bus Reliable messaging Event synchronization 2 Lesson #4
  • 101.
    Lesson #4 I wouldlike to know if user before placing an Order removes Items if we propose them more useful articles with our recommendation system 101
  • 102.
    102 But...  We don’thave a History Lesson #4
  • 103.
  • 105.
    105 Lesson #4 Skyscraper Apartment block Smallhouse Wood house (tools cot) Basic ingredients: Bricks, concrete, woods, etc. Simple architecture, does not scale, hard to maintain, often monolithic Recipe 1: Basic layered architecture Receipe 4: Hexagonal with CQRS + DDD Easily scalable and high performances Domain centric, refactorable and evolable Recipe 2: N- layered architecture with DI Decoupled and easy to integrate with external systems Receipe 3: Hexagonal with basic CQRS Lesson #4
  • 106.
    106 Basic CQRS +DDD + Async Ingredients Good OOP skills SOLID principles Domain Driven Design modeling Good knowledge of messaging infrastructure Difficulty: Time: Long Term Preparation: Gather business intent in form of Commands, map it to business events and synchronize everything async 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 Domain Repositor y 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 Repositor y Lesson #4
  • 107.
    Lesson #5  Allyou need to do is using your events 10 7
  • 108.
    Lesson #5 But forlegal thing, we would like an audit log system 10 8
  • 109.
    Lesson #5 We needa time machine… 10 9
  • 110.
    110 Order Order lineItem Shipping information Order Created Added 2 items 245 Added 3 items 455 Removed 2 items 245 Added shipping info Order placed Event Sourcing  Event as a storage mechanism Lesson #5
  • 111.
    111 Order Created Added 2items 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 Event Sourcing: Rolling snapshot Lesson #5
  • 112.
    112 Domain Event Store Read ModelApplication service DB Read UI Command Handler Command Bus Event Bus Read model generator Another context application Command Event Dependency Architecture v5 Lesson #5
  • 113.
    113 Domain Event Store Read ModelApplication service DB Read DB Write Read ModelApplication service DB Read UI Command Handler Command Bus Event Bus Read model generator ACL Command Handler Domain Repository Read model generator Command Event Dependency Architecture v5.1 Lesson #5
  • 114.
    114 Domain Event Store Read ModelApplication service UI Command Handler Command Bus Event Bus Another context application Command Event Dependency Event Sourcing Lesson #5
  • 115.
    Lesson #5 Our systemseems to be on the right track now!! 115
  • 116.
    116 Lesson #5 Skyscraper Apartment block Smallhouse Wood house (tools cot) Basic ingredients: Bricks, concrete, woods, etc. Simple architecture, does not scale, hard to maintain, often monolithic Recipe 1: Basic layered architecture Domain centric, refactorable and evolable Recipe 2: N- layered architecture with DI Decoupled and easy to integrate with external systems Receipe 3: Hexagonal with basic CQRS Easily scalable and high performances Receipe 4: Heagonal with CQRS + DDD Robust and resilient Receipe 5: Heagonal with CQRS + DDD + ES Lesson #5
  • 117.
    117 Basic CQRS +DDD + ES Ingredients Good OOP skills SOLID principles Domain Driven Design modeling Good knowledge of messaging infrastructure Functional thinking Difficulty: Time: Long Term Preparation: Make your events talk 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 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 Repository Read model generator Lesson #5
  • 118.
  • 119.
    119 What CQRS isnot? A final word
  • 120.
    120 Is CQRS forme?  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 A final word
  • 121.
    121 It’s only thebeginning of journey  Aggregates  Uniqueness checking  Existence checking  Replaying of events (Event Sourced)  Long running workflows A final word
  • 122.
    122 Referencials  Greg Young’sSimplest Solution: https://github.com/gregoryyoung/m-r  Simple CQRS demo approach: https://www.youtube.com/watch?v=tTbHR5KScEE  Fowler’s book  DDD book by Eric Evans [Blue Book]  DDD book by Vernon [Red Book] A final word
  • 123.