Top Banner
CQRS recepies HOW TO BUILD YOUR ARCHITECTURE Francesco Garavaglia 04/2016
123

CQRS recepies

Apr 15, 2017

Download

Software

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: CQRS recepies

CQRS recepiesHOW TO BUILD YOUR ARCHITECTURE

Francesco Garavaglia

04/2016

Page 2: CQRS recepies

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

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

What problems

are we trying to

solve?

4

Page 5: CQRS recepies

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

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

What’s wrong?

7

Page 8: CQRS recepies

8

Nothing

Page 10: CQRS recepies

10

Page 11: CQRS recepies

11

Wait,

Breath & re-think

Page 12: CQRS recepies

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

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

14

One big model to capture it ALL

….

…..…..

….…..…..

….…..…..

….

…..…..

The Problem

Page 15: CQRS recepies
Page 16: CQRS recepies

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

17

The database determines our scalabilityThe Problem

Page 18: CQRS recepies

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

19

Alternatively we can use Read replicas

Master Slave SlaveSlaveSlave

You’re now eventually consistent

The Problem

Page 20: CQRS recepies

20

Or introduce caching…

What’s your synchronization mechanism?

?

The Problem

Page 21: CQRS recepies

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

22

Try new SolutionThe Problem

Page 23: CQRS recepies

Architecture

Pyramid

23

Skyscraper

Apartment block

Small house

Wood house (tools cot)

Basic ingredients: Bricks, concrete, woods, etc.

Page 24: CQRS recepies

What about

software????

24A brief history

Page 25: CQRS recepies

A brief history

A brief history:

Once upon a

time....

25

Page 26: CQRS recepies

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

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

A brief history

Developers

have started

their work....

28

Page 29: CQRS recepies

A brief history

Developers

continue their

works....

29

Page 30: CQRS recepies

A brief history

After a while...

30

Page 31: CQRS recepies

A brief history

E-Commerce

portal

Architecture

User Interface

Domain Logic

Data Access Layer

DB

31

Page 32: CQRS recepies

A brief history

But another

feature was

asked by the

business...

32

Page 33: CQRS recepies

... And

developers start

to work again...

33A brief history

Page 34: CQRS recepies

A brief history

... After one

year...

34

Page 35: CQRS recepies

A brief history

The Monolith

appears!

35

Page 36: CQRS recepies

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

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

Lesson #1

We need a

refactor!!!

38

Page 39: CQRS recepies

Lesson #2

How do we

refator a

monolith?

39

Page 40: CQRS recepies

Lesson #2

Decouple every component

Evolve domain

independently.

Handle business needs easier

40

Page 41: CQRS recepies

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

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

Lesson #2

Business asks for

more features

for Orders,

Suppliers, stuff....

43

Page 44: CQRS recepies

Lesson #2

We need a

refactor!!!

44

Page 45: CQRS recepies

Lesson #2

Add more

Layers!!!!

45

Page 46: CQRS recepies

46

Decoupling (2)Lesson #2

Page 47: CQRS recepies

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

Lesson #2

We need more

data on UI and

different views

per user or

device...

48

Page 49: CQRS recepies

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

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

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
Page 53: CQRS recepies

Lesson #3

Read and Write from

separate logics

CQRS

53

Page 54: CQRS recepies

Lesson #3

CQRS?

54

Page 55: CQRS recepies

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

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

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

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

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

60

CQRS: Query

Does not change state

Has return value

Also a type of message

Lesson #3

Page 61: CQRS recepies

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

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

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

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

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

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

67

Architecture v3Lesson #3

Page 68: CQRS recepies

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

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

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

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

Lesson #4

Where do we

put the major

effort?

72

Page 73: CQRS recepies

What is the strategic

advantage for the

company?

73Lesson #4

Page 74: CQRS recepies

But how do we find

the best model for a

business…

74Lesson #4

Page 75: CQRS recepies

Lesson #4

Ask to the Business

75

Page 76: CQRS recepies

Lesson #4

Event Storming = Domain

Discovery tool of the

business

76

Page 77: CQRS recepies

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

Lesson #4

Finally, Events!

We think only about

them!

78

Page 79: CQRS recepies

Lesson #4

One Event, One handler: the

aggregates

Event + Aggregates = DDD

79

Page 80: CQRS recepies

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

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

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

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

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

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

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

Lesson #4

We need a new

feature: concert

ticket sell

87

Page 88: CQRS recepies

Lesson #4

Done

88

Page 89: CQRS recepies

Lesson #4

System is unusable:

users are blocked

89

Page 90: CQRS recepies

Lesson #4

WTF…

90

Page 91: CQRS recepies

91

Page 92: CQRS recepies

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

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

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

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

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

Lesson #4

There is a trap

Views are not refreshed

immediately

Event syncronization

97

Page 98: CQRS recepies

Lesson #4 98

There is a trap event synchronization

Page 99: CQRS recepies

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

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

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

102

But...

We don’t have a History

Lesson #4

Page 103: CQRS recepies

So?

What’s Next

move?

103

Page 104: CQRS recepies
Page 105: CQRS recepies

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

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

Lesson #5

All you need to do is using

your events

10

7

Page 108: CQRS recepies

Lesson #5

But for legal thing, we would like an audit log

system

10

8

Page 109: CQRS recepies

Lesson #5

We need a time

machine…

10

9

Page 110: CQRS recepies

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

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

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

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

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

Lesson #5

Our system seems to be on the right track now!!

115

Page 116: CQRS recepies

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

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

THIS IS CQRS

Page 119: CQRS recepies

119

What CQRS is not?A final word

Page 120: CQRS recepies

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

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

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