CQRS recepies
-
Upload
francesco-garavaglia -
Category
Software
-
view
144 -
download
3
Transcript of CQRS recepies
![Page 1: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/1.jpg)
CQRS recepiesHOW TO BUILD YOUR ARCHITECTURE
Francesco Garavaglia
04/2016
![Page 2: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/2.jpg)
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
![Page 3: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/3.jpg)
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
![Page 4: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/4.jpg)
What problems
are we trying to
solve?
4
![Page 5: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/5.jpg)
Typical ”Fitting-
all” architecture
Client
Remote Facade
Application Service
Data Access Layer
Data Storage
Domain ObjectDomain
Object
DTO DTO
Infr
ast
ruc
ture
(
log
, se
cu
rity
, e
tc.)
The Problem
![Page 6: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/6.jpg)
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
![Page 7: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/7.jpg)
What’s wrong?
7
![Page 8: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/8.jpg)
8
Nothing
![Page 10: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/10.jpg)
10
![Page 11: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/11.jpg)
11
Wait,
Breath & re-think
![Page 12: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/12.jpg)
12
Typical ”Fitting-all” architecture
Client
Remote Facade
Application Service
Data Access Layer
Data Storage
Domain
Object
Domain
Object
DTO DTO
Infr
ast
ruc
ture
(
log
, se
cu
rity
, e
tc.) 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
![Page 13: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/13.jpg)
13
Many perspectives on data
Customer
Online Ordering System
Pricing
Inventory
Sales
Product
Unit PricePromotional PricePromotion End Date
Stock Keeping Unit (SKU)Quantity On Hand (QOH)Location Code
PriceQuantity OrderedName
What about the lifecycles for the data?
The Problem
![Page 14: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/14.jpg)
14
One big model to capture it ALL
….
…..…..
….…..…..
….…..…..
….
…..…..
The Problem
![Page 15: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/15.jpg)
![Page 16: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/16.jpg)
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
![Page 17: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/17.jpg)
17
The database determines our scalabilityThe Problem
![Page 18: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/18.jpg)
18
And databases often scale poorly
To solve the
performance
problems for a few,
you have to upgrade
it all
The Problem
![Page 19: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/19.jpg)
19
Alternatively we can use Read replicas
Master Slave SlaveSlaveSlave
You’re now eventually consistent
The Problem
![Page 20: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/20.jpg)
20
Or introduce caching…
What’s your synchronization mechanism?
?
The Problem
![Page 21: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/21.jpg)
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
Co
mp
lexity
Complexity of code and solutionThe Problem
![Page 22: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/22.jpg)
22
Try new SolutionThe Problem
![Page 23: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/23.jpg)
Architecture
Pyramid
23
Skyscraper
Apartment block
Small house
Wood house (tools cot)
Basic ingredients: Bricks, concrete, woods, etc.
![Page 24: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/24.jpg)
What about
software????
24A brief history
![Page 25: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/25.jpg)
A brief history
A brief history:
Once upon a
time....
25
![Page 26: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/26.jpg)
A brief history
One upon a
time, a
marketing team
came in to
announce to
developers what
they have sold
26
![Page 27: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/27.jpg)
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
![Page 28: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/28.jpg)
A brief history
Developers
have started
their work....
28
![Page 29: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/29.jpg)
A brief history
Developers
continue their
works....
29
![Page 30: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/30.jpg)
A brief history
After a while...
30
![Page 31: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/31.jpg)
A brief history
E-Commerce
portal
Architecture
User Interface
Domain Logic
Data Access Layer
DB
31
![Page 32: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/32.jpg)
A brief history
But another
feature was
asked by the
business...
32
![Page 33: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/33.jpg)
... And
developers start
to work again...
33A brief history
![Page 34: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/34.jpg)
A brief history
... After one
year...
34
![Page 35: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/35.jpg)
A brief history
The Monolith
appears!
35
![Page 36: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/36.jpg)
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
![Page 37: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/37.jpg)
37
Basic Layered Architecture
Ingredients
Basic coding skillsSome 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
![Page 38: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/38.jpg)
Lesson #1
We need a
refactor!!!
38
![Page 39: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/39.jpg)
Lesson #2
How do we
refator a
monolith?
39
![Page 40: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/40.jpg)
Lesson #2
Decouple every component
Evolve domain
independently.
Handle business needs easier
40
![Page 41: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/41.jpg)
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
![Page 42: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/42.jpg)
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
![Page 43: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/43.jpg)
Lesson #2
Business asks for
more features
for Orders,
Suppliers, stuff....
43
![Page 44: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/44.jpg)
Lesson #2
We need a
refactor!!!
44
![Page 45: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/45.jpg)
Lesson #2
Add more
Layers!!!!
45
![Page 46: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/46.jpg)
46
Decoupling (2)Lesson #2
![Page 47: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/47.jpg)
47
Layered Architecture v.2
UI
OrderViewModel
Order
OrderController
OrderMapper IOrderMapper
SqlOrderRepository IOrderRepository
DB
Pre
sen
tatio
nD
om
ain
Infr
ast
ruc
ture
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
![Page 48: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/48.jpg)
Lesson #2
We need more
data on UI and
different views
per user or
device...
48
![Page 49: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/49.jpg)
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
![Page 50: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/50.jpg)
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
![Page 51: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/51.jpg)
51
N-Layered architecture with DI
Ingredients
OOP skillsWith SOLID principles would be event betterORMs and IOCsSome 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
![Page 52: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/52.jpg)
![Page 53: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/53.jpg)
Lesson #3
Read and Write from
separate logics
CQRS
53
![Page 54: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/54.jpg)
Lesson #3
CQRS?
54
![Page 55: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/55.jpg)
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
![Page 56: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/56.jpg)
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
![Page 57: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/57.jpg)
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);
//...
}
![Page 58: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/58.jpg)
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
![Page 59: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/59.jpg)
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)
{ …. }
}
![Page 60: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/60.jpg)
60
CQRS: Query
Does not change state
Has return value
Also a type of message
Lesson #3
![Page 61: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/61.jpg)
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
![Page 62: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/62.jpg)
62
How does CQRS work?Lesson #3
Create Order
Change Address
Co
mm
an
d B
us
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 modelDomain
Handles
Commands
![Page 63: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/63.jpg)
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
![Page 64: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/64.jpg)
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
![Page 65: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/65.jpg)
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
![Page 66: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/66.jpg)
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
![Page 67: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/67.jpg)
67
Architecture v3Lesson #3
![Page 68: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/68.jpg)
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
![Page 69: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/69.jpg)
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
![Page 70: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/70.jpg)
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
![Page 71: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/71.jpg)
71
Basic CQRS
Ingredients
OOP skillsSOLID principlesDomain 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
![Page 72: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/72.jpg)
Lesson #4
Where do we
put the major
effort?
72
![Page 73: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/73.jpg)
What is the strategic
advantage for the
company?
73Lesson #4
![Page 74: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/74.jpg)
But how do we find
the best model for a
business…
74Lesson #4
![Page 75: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/75.jpg)
Lesson #4
Ask to the Business
75
![Page 76: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/76.jpg)
Lesson #4
Event Storming = Domain
Discovery tool of the
business
76
![Page 77: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/77.jpg)
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
![Page 78: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/78.jpg)
Lesson #4
Finally, Events!
We think only about
them!
78
![Page 79: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/79.jpg)
Lesson #4
One Event, One handler: the
aggregates
Event + Aggregates = DDD
79
![Page 80: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/80.jpg)
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
![Page 81: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/81.jpg)
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
![Page 82: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/82.jpg)
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
![Page 83: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/83.jpg)
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
![Page 84: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/84.jpg)
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
![Page 85: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/85.jpg)
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
ServicesPorts
Adapters
Lesson #4
![Page 86: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/86.jpg)
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
![Page 87: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/87.jpg)
Lesson #4
We need a new
feature: concert
ticket sell
87
![Page 88: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/88.jpg)
Lesson #4
Done
88
![Page 89: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/89.jpg)
Lesson #4
System is unusable:
users are blocked
89
![Page 90: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/90.jpg)
Lesson #4
WTF…
90
![Page 91: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/91.jpg)
91
![Page 92: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/92.jpg)
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
![Page 93: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/93.jpg)
93
Different architectures
Composite UI
UI
Data Access Layer
Web / Application Tier
Background server Tier
Storage Tier
DDD layered
application
Write
model
Read
model
Legacyapplication
Domain A Domain B Domain C Domain D
CRUD architecture (simple non-core
domain functionality)
DDD (core domainfunctionality)
CQRS (core domainfunctionality)
Legacy subsystem
Lesson #4
![Page 94: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/94.jpg)
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 v4Lesson #4
Command Bus
![Page 95: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/95.jpg)
95
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.1Lesson #4
![Page 96: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/96.jpg)
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.2Lesson #4
![Page 97: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/97.jpg)
Lesson #4
There is a trap
Views are not refreshed
immediately
Event syncronization
97
![Page 98: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/98.jpg)
Lesson #4 98
There is a trap event synchronization
![Page 99: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/99.jpg)
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 synchronizationLesson #4
![Page 100: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/100.jpg)
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 BusReliable messaging
Event synchronization 2Lesson #4
![Page 101: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/101.jpg)
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
![Page 102: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/102.jpg)
102
But...
We don’t have a History
Lesson #4
![Page 103: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/103.jpg)
So?
What’s Next
move?
103
![Page 104: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/104.jpg)
![Page 105: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/105.jpg)
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
![Page 106: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/106.jpg)
106
Basic CQRS + DDD + Async
Ingredients
Good OOP skillsSOLID principlesDomain Driven Design modelingGood 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
DomainRepositor
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
DomainRepositor
y
Lesson #4
![Page 107: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/107.jpg)
Lesson #5
All you need to do is using
your events
10
7
![Page 108: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/108.jpg)
Lesson #5
But for legal thing, we would like an audit log
system
10
8
![Page 109: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/109.jpg)
Lesson #5
We need a time
machine…
10
9
![Page 110: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/110.jpg)
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
![Page 111: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/111.jpg)
111
Order Created
Added 2 items 245
Added 3 items 455
Removed 2 items 245
Added shipping info
Order placed
Snapshot
Put on stackAdded 3 items 455
Removed 2 items 245
Added shipping info
Order placed
Snapshot
Event Sourcing: Rolling snapshotLesson #5
![Page 112: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/112.jpg)
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 v5Lesson #5
![Page 113: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/113.jpg)
113
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
Architecture v5.1Lesson #5
![Page 114: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/114.jpg)
114
Domain
Event Store
Read Model Application service
UI
Command Handler
Command Bus
Event Bus
Another context application
Command Event Dependency
Event SourcingLesson #5
![Page 115: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/115.jpg)
Lesson #5
Our system seems to be on the right track now!!
115
![Page 116: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/116.jpg)
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
![Page 117: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/117.jpg)
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
![Page 118: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/118.jpg)
THIS IS CQRS
![Page 119: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/119.jpg)
119
What CQRS is not?A final word
![Page 120: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/120.jpg)
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
![Page 121: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/121.jpg)
121
It’s only the beginning of journey
Aggregates
Uniqueness checking
Existence checking
Replaying of events (Event Sourced)
Long running workflows
A final word
![Page 122: CQRS recepies](https://reader031.fdocuments.us/reader031/viewer/2022021500/587ac6431a28ab760f8b45ff/html5/thumbnails/122.jpg)
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