SlideShare une entreprise Scribd logo
1  sur  54
Télécharger pour lire hors ligne
CQRS & EVENT SOURCING
IN THE WILD
MICHIEL ROOK
➤ Java, PHP & Scala
developer
➤ Consultant, trainer,
speaker
➤ Dutch Web Alliance
➤ make.io
➤ Maintainer of Phing
➤ @michieltcs
YOU
RAISE YOUR HAND
IF YOU HAVE
heard about CQRS / Event Sourcing
RAISE YOUR HAND
IF YOU HAVE
heard about CQRS / Event Sourcing
followed a tutorial, built a hobby project
RAISE YOUR HAND
IF YOU HAVE
heard about CQRS / Event Sourcing
followed a tutorial, built a hobby project
used it in production
RAISE YOUR HAND
IF YOU HAVE
TOPICS
➤ Quick recap
➤ Replays and rebuilds
➤ Event versioning
➤ Concurrency
➤ Scale
QUICK RECAP
' Event Sourcing ensures that all
changes to application state are stored
as a sequence of events.
-Martin Fowler
ACTIVE RECORD VS. EVENT SOURCING
Account
number
Balance
12345678 €€ 50,00
... ...
Money Withdrawn
Account number 12345678
Amount €€ 50,00
Money Deposited
Account number 12345678
Amount €€ 100,00
Account Created
Account number 12345678
COMMANDS TO EVENTS
Deposit Money
Account number 12345678
Amount €€ 100,00
Money Deposited
Account number 12345678
Amount €€ 100,00
class DepositMoney {

public $accountNumber;

public $amount;

}
class MoneyDeposited {

public $accountNumber;

public $amount;

public $timestamp;

}
function depositMoney(DepositMoney $command) {

$this->apply(new MoneyDeposited($command->accountNumber,

$command->amount, date()));

}
AGGREGATES
class BankAccount {

public $accountNumber;

public $balance;



// command handlers...



public function applyAccountCreated(AccountCreated $event) {

$this->accountNumber = $event->accountNumber;

$this->balance = 0;

}



public function applyMoneyDeposited(MoneyDeposited $event) {

$this->balance += $event->amount;

}



public function applyMoneyWithdrawn(MoneyWithdrawn $event) {

$this->balance -= $event->amount;

}

}
AGGREGATE STATE
Account
number
Balance
12345678 €€ 0,00
Money Withdrawn
Account number 12345678
Amount €€ 50,00
Money Deposited
Account number 12345678
Amount €€ 100,00
Account Created
Account number 56789012
Account
number
Balance
12345678 €€ 100,00
Account
number
Balance
12345678 €€ 50,00
CQRS
➤ Command Query Responsibility Segregation
➤ Separate writes (events) and reads (UI)
➤ Optimize for reads!
Domain
Event Bus
Event Handlers
Command
Repository
Data Layer
Database Database
Event
Store
commands
events
events
queries DTOs
Aggregates
PROS AND CONS
➤ Domain fit
➤ Testing
➤ Audit trail
➤ Scalability
➤ Complexity
➤ Library support / maturity
DISCLAIMER
REPLAYS AND REBUILDS
PROJECTIONS AND READ MODELS
User Registered
User Registered
User Unregistered Number of active users?
PROJECTIONS AND READ MODELS
User Registered
User Deactivated
User Reactivated
Number of active users?
User Registered
User Unregistered
PROJECTIONS AND READ MODELS
User Registered Event Handler
Number of
active users
+1
User Unregistered Event Handler
Number of
active users
-1
PROJECTIONS AND READ MODELS
Events Event Handler(s) Storage
ELASTICSEARCH
class CompanyRegistered {

public $companyId;

public $name;

public $street;

public $city;

}



function handleCompanyRegistered(CompanyRegistered $event) {

$this->elasticsearch->index([

'index' => 'companies',

'type' => 'company',

'id' => $event->companyId,

'body' => [

'name' => $event->name,

'address' => [

'street' => $event->street,

'city' => $event->city

]

]

]);

}
READ MODEL UPDATES
➤ New type
➤ New structure
➤ Based on existing events
➤ Generate from scratch?
REBUILDING
Stop
application
Remove
old read
model
Loop over
events
Apply to
read model
Start
application
ZERO DOWNTIME
Loop over
existing
events
Apply to
new read
model
Apply
queued
events
Start using
new read
model
New events Queue
ELASTICSEARCH: MAPPING CHANGE
Create
index with
new
mapping
Reindex
existing
documents
Apply
queued
events
Start using
new index
New events Queue
CHALLENGE: LONG RUNNING REBUILDS
➤ Alternatives
➤ Distributed
➤ In memory
➤ Partial
➤ Background
CHALLENGE: SIDE EFFECTS
User Registered
User Id 123abc
Email Address test@example.net
Event Handler
Exclude during replays!
CHALLENGE: TRANSACTIONS
Event Handler
Event Handler
Event
Event Handler
Event Handler ?
CHALLENGE: EVENTUAL CONSISTENCY
➤ Asynchronous event handlers
➤ Reads eventually return the same value
➤ Compare with ACID
EVENT VERSIONING
DILEMMA
➤ New business requirements
➤ Refactoring
➤ New view on events
NEW EVENTS / VERSIONS
➤ No longer relevant
➤ Renamed
➤ Additional or renamed field(s)
➤ Too coarse, too fine
SUPPORT YOUR LEGACY?
➤ Events are immutable
➤ Correct (incorrect) old events with new events
UPCASTING
Event Store
UserRegistered_V1
Upcaster
UserRegistered_V2
Event Handler
UPCASTING
class UserRegistered_V1 {

public $userId;

public $name;

public $timestamp;

}



class UserRegistered_V2 {

public $userId;

public $name;

public $date;

}



function upcast($event): array {

if (!$event instanceof UserRegistered_V1) {

return [];

}

return [

new UserRegistered_V2($event->userId, $event->name,

$event->timestamp->format("Y-m-d"))

];

}
REWRITING HISTORY
Load (subset of) events
Deserialize
Modify
Serialize
Save/replace
THINGS TO BE AWARE OF
Upcasting
➤ Performance
➤ Complexity
➤ Existing projections not
automatically updated
Rewriting events
➤ Running code that
depends on old structure
➤ Breaking serialization
➤ Changing wrong events
CONCURRENCY
CONCURRENT COMMANDS
Withdraw Money
Account number 12345678
Amount €€ 50,00
Deposit Money
Account number 12345678
Amount €€ 100,00
?
PESSIMISTIC LOCKING
Withdraw Money
Account number 12345678
Amount €€ 50,00
Deposit Money
Account number 12345678
Amount €€ 100,00
Account
number
Balance
12345678 €€ 100,00
Account
number
Balance
12345678 €€ 50,00
wait for lock
lock
OPTIMISTIC LOCKING
Withdraw Money
Account number 12345678
Amount €€ 50,00
version 1
Deposit Money
Account number 12345678
Amount €€ 100,00
version 1
Account
number
Balance
12345678 €€ 100,00
version 2
ConcurrencyException
SCALE
PERFORMANCE
➤ Server
➤ Database
➤ Framework
➤ Language
STORAGE
➤ #events
➤ #aggregates
➤ #events_per_aggregate
➤ Serializer
➤ Speed
➤ Payload size
➤ Costs
SNAPSHOTS
Events
1 Account Created
2 Money Deposited
3 Money Withdrawn
4 Money Deposited
SNAPSHOT
5 Money Withdrawn
Events
1 Account Created
2 Money Deposited
3 Money Withdrawn
4 Money Deposited
5 Money Withdrawn
SHARDING
➤ Aggregate Id, Type, Event Timestamp, ...
➤ Rebalancing
➤ Distribution
ARCHIVING EVENTS
➤ Reduce working set
➤ Inactive / deleted aggregates
➤ Historic / irrelevant events
➤ Cheaper storage
FRAMEWORK COMPARISON
Framework Upcasting Snapshots Replaying
Broadway
(PHP)
No (PR) No (PR) Not in core
Prooph
(PHP)
MessageFactory
Yes, triggers on
event count
Example code,
off line
Axon
(Java/Scala)
Upcaster /
UpcasterChain
Yes, triggers on
event count
Yes,
ReplayingCluster
Akka
Persistence
(Java/Scala)
Event Adapter
Yes, decided by
actor
Yes
BROADWAY VS PROOPH
class TodoItem extends EventSourcedAggregateRoot {

private $itemId;



public function __construct(PostTodo $command) {

$this->apply(new TodoPosted($command->getItemId()));

}



public function getAggregateRootId()

{

return $this->itemId;

}



public function applyTodoPosted(TodoPosted $event) {

echo "Posted: " . $event->getItemId() . "n";

}

}
BROADWAY VS PROOPH
class TodoItem extends AggregateRoot {

private $itemId;



public function __construct(PostTodo $command) {

$this->recordThat(new TodoPosted($command->getItemId()));

}



protected function aggregateId() {

return $this->itemId;

}



public function whenTodoPosted(TodoPosted $event) {

echo "Posted: " . $event->getItemId() . "n";

}

}
THANK YOU!

Contenu connexe

Tendances

DDD Framework for Java: JdonFramework
DDD Framework for Java: JdonFrameworkDDD Framework for Java: JdonFramework
DDD Framework for Java: JdonFrameworkbanq jdon
 
Event Sourcing with Microservices
Event Sourcing with MicroservicesEvent Sourcing with Microservices
Event Sourcing with MicroservicesRalph Winzinger
 
Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...Chris Richardson
 
A practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSA practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSRobert Lemke
 
Going Serverless with CQRS on AWS
Going Serverless with CQRS on AWSGoing Serverless with CQRS on AWS
Going Serverless with CQRS on AWSAnton Udovychenko
 
CQRS + Event Sourcing
CQRS + Event SourcingCQRS + Event Sourcing
CQRS + Event SourcingMike Bild
 
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with Sagas
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with SagasJavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with Sagas
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with SagasChris Richardson
 
Lighning Talk: Event-Driven architecture for microservices
Lighning Talk: Event-Driven architecture for microservicesLighning Talk: Event-Driven architecture for microservices
Lighning Talk: Event-Driven architecture for microservicesMartins Sipenko
 
Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Chris Richardson
 
Developing microservices with aggregates (devnexus2017)
Developing microservices with aggregates (devnexus2017)Developing microservices with aggregates (devnexus2017)
Developing microservices with aggregates (devnexus2017)Chris Richardson
 
Event Sourcing - Greg Young
Event Sourcing - Greg YoungEvent Sourcing - Greg Young
Event Sourcing - Greg YoungJAXLondon2014
 
Developing microservices with aggregates (melbourne)
Developing microservices with aggregates (melbourne)Developing microservices with aggregates (melbourne)
Developing microservices with aggregates (melbourne)Chris Richardson
 
A Pattern Language for Microservices (@futurestack)
A Pattern Language for Microservices (@futurestack)A Pattern Language for Microservices (@futurestack)
A Pattern Language for Microservices (@futurestack)Chris Richardson
 
Event sourcing with Eventuate
Event sourcing with EventuateEvent sourcing with Eventuate
Event sourcing with EventuateKnoldus Inc.
 
Microservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event SourcingMicroservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event SourcingBen Wilcock
 
Microservices in Java and Scala (sfscala)
Microservices in Java and Scala (sfscala)Microservices in Java and Scala (sfscala)
Microservices in Java and Scala (sfscala)Chris Richardson
 
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...Chris Richardson
 
Events, Picos, and Microservices
Events, Picos, and MicroservicesEvents, Picos, and Microservices
Events, Picos, and MicroservicesPhil Windley
 
Building microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootBuilding microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootChris Richardson
 
#JaxLondon: Building microservices with Scala, functional domain models and S...
#JaxLondon: Building microservices with Scala, functional domain models and S...#JaxLondon: Building microservices with Scala, functional domain models and S...
#JaxLondon: Building microservices with Scala, functional domain models and S...Chris Richardson
 

Tendances (20)

DDD Framework for Java: JdonFramework
DDD Framework for Java: JdonFrameworkDDD Framework for Java: JdonFramework
DDD Framework for Java: JdonFramework
 
Event Sourcing with Microservices
Event Sourcing with MicroservicesEvent Sourcing with Microservices
Event Sourcing with Microservices
 
Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...
 
A practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSA practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRS
 
Going Serverless with CQRS on AWS
Going Serverless with CQRS on AWSGoing Serverless with CQRS on AWS
Going Serverless with CQRS on AWS
 
CQRS + Event Sourcing
CQRS + Event SourcingCQRS + Event Sourcing
CQRS + Event Sourcing
 
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with Sagas
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with SagasJavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with Sagas
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with Sagas
 
Lighning Talk: Event-Driven architecture for microservices
Lighning Talk: Event-Driven architecture for microservicesLighning Talk: Event-Driven architecture for microservices
Lighning Talk: Event-Driven architecture for microservices
 
Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)
 
Developing microservices with aggregates (devnexus2017)
Developing microservices with aggregates (devnexus2017)Developing microservices with aggregates (devnexus2017)
Developing microservices with aggregates (devnexus2017)
 
Event Sourcing - Greg Young
Event Sourcing - Greg YoungEvent Sourcing - Greg Young
Event Sourcing - Greg Young
 
Developing microservices with aggregates (melbourne)
Developing microservices with aggregates (melbourne)Developing microservices with aggregates (melbourne)
Developing microservices with aggregates (melbourne)
 
A Pattern Language for Microservices (@futurestack)
A Pattern Language for Microservices (@futurestack)A Pattern Language for Microservices (@futurestack)
A Pattern Language for Microservices (@futurestack)
 
Event sourcing with Eventuate
Event sourcing with EventuateEvent sourcing with Eventuate
Event sourcing with Eventuate
 
Microservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event SourcingMicroservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event Sourcing
 
Microservices in Java and Scala (sfscala)
Microservices in Java and Scala (sfscala)Microservices in Java and Scala (sfscala)
Microservices in Java and Scala (sfscala)
 
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...
 
Events, Picos, and Microservices
Events, Picos, and MicroservicesEvents, Picos, and Microservices
Events, Picos, and Microservices
 
Building microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootBuilding microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring Boot
 
#JaxLondon: Building microservices with Scala, functional domain models and S...
#JaxLondon: Building microservices with Scala, functional domain models and S...#JaxLondon: Building microservices with Scala, functional domain models and S...
#JaxLondon: Building microservices with Scala, functional domain models and S...
 

Similaire à CQRS & event sourcing in the wild

CQRS & Event Sourcing in the wild (ScotlandPHP 2016)
CQRS & Event Sourcing in the wild (ScotlandPHP 2016)CQRS & Event Sourcing in the wild (ScotlandPHP 2016)
CQRS & Event Sourcing in the wild (ScotlandPHP 2016)Michiel Rook
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
Kafka as an Event Store - is it Good Enough?
Kafka as an Event Store - is it Good Enough?Kafka as an Event Store - is it Good Enough?
Kafka as an Event Store - is it Good Enough?Guido Schmutz
 
Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019
Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019
Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019confluent
 
Introduction to Event Sourcing in PHP
Introduction to Event Sourcing in PHPIntroduction to Event Sourcing in PHP
Introduction to Event Sourcing in PHPEvan McMahon
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right wayThibaud Desodt
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
A Journey with React
A Journey with ReactA Journey with React
A Journey with ReactFITC
 
FamilySearch Reference Client
FamilySearch Reference ClientFamilySearch Reference Client
FamilySearch Reference ClientDallan Quass
 
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...Coupa Software
 
Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)guiwoda
 
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...tdc-globalcode
 
Kafka as an event store - is it good enough?
Kafka as an event store - is it good enough?Kafka as an event store - is it good enough?
Kafka as an event store - is it good enough?Guido Schmutz
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Joao Lucas Santana
 
How to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR RestHow to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR Restshravan kumar chelika
 
Who Needs Ruby When You've Got CodeIgniter
Who Needs Ruby When You've Got CodeIgniterWho Needs Ruby When You've Got CodeIgniter
Who Needs Ruby When You've Got CodeIgniterciconf
 
CQRS / ES & DDD Demystified
CQRS / ES & DDD DemystifiedCQRS / ES & DDD Demystified
CQRS / ES & DDD DemystifiedVic Metcalfe
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application frameworkDustin Filippini
 

Similaire à CQRS & event sourcing in the wild (20)

CQRS & Event Sourcing in the wild (ScotlandPHP 2016)
CQRS & Event Sourcing in the wild (ScotlandPHP 2016)CQRS & Event Sourcing in the wild (ScotlandPHP 2016)
CQRS & Event Sourcing in the wild (ScotlandPHP 2016)
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Kafka as an Event Store - is it Good Enough?
Kafka as an Event Store - is it Good Enough?Kafka as an Event Store - is it Good Enough?
Kafka as an Event Store - is it Good Enough?
 
Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019
Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019
Kafka as an Event Store (Guido Schmutz, Trivadis) Kafka Summit NYC 2019
 
Introduction to Event Sourcing in PHP
Introduction to Event Sourcing in PHPIntroduction to Event Sourcing in PHP
Introduction to Event Sourcing in PHP
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
A Journey with React
A Journey with ReactA Journey with React
A Journey with React
 
FamilySearch Reference Client
FamilySearch Reference ClientFamilySearch Reference Client
FamilySearch Reference Client
 
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...
 
Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)
 
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
 
Kafka as an event store - is it good enough?
Kafka as an event store - is it good enough?Kafka as an event store - is it good enough?
Kafka as an event store - is it good enough?
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
 
How to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR RestHow to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR Rest
 
Who Needs Ruby When You've Got CodeIgniter
Who Needs Ruby When You've Got CodeIgniterWho Needs Ruby When You've Got CodeIgniter
Who Needs Ruby When You've Got CodeIgniter
 
Patterns for Building Streaming Apps
Patterns for Building Streaming AppsPatterns for Building Streaming Apps
Patterns for Building Streaming Apps
 
CQRS / ES & DDD Demystified
CQRS / ES & DDD DemystifiedCQRS / ES & DDD Demystified
CQRS / ES & DDD Demystified
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application framework
 
Presentation Paul
Presentation PaulPresentation Paul
Presentation Paul
 

Plus de Michiel Rook

The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)Michiel Rook
 
The road to continuous deployment (DomCode September 2016)
The road to continuous deployment (DomCode September 2016)The road to continuous deployment (DomCode September 2016)
The road to continuous deployment (DomCode September 2016)Michiel Rook
 
The road to continuous deployment: a case study (DPC16)
The road to continuous deployment: a case study (DPC16)The road to continuous deployment: a case study (DPC16)
The road to continuous deployment: a case study (DPC16)Michiel Rook
 
Building and Deploying PHP apps with Phing
Building and Deploying PHP apps with PhingBuilding and Deploying PHP apps with Phing
Building and Deploying PHP apps with PhingMichiel Rook
 
Building and deploying PHP applications with Phing
Building and deploying PHP applications with PhingBuilding and deploying PHP applications with Phing
Building and deploying PHP applications with PhingMichiel Rook
 
Deploying PHP applications with Phing
Deploying PHP applications with PhingDeploying PHP applications with Phing
Deploying PHP applications with PhingMichiel Rook
 
Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Michiel Rook
 

Plus de Michiel Rook (7)

The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)
 
The road to continuous deployment (DomCode September 2016)
The road to continuous deployment (DomCode September 2016)The road to continuous deployment (DomCode September 2016)
The road to continuous deployment (DomCode September 2016)
 
The road to continuous deployment: a case study (DPC16)
The road to continuous deployment: a case study (DPC16)The road to continuous deployment: a case study (DPC16)
The road to continuous deployment: a case study (DPC16)
 
Building and Deploying PHP apps with Phing
Building and Deploying PHP apps with PhingBuilding and Deploying PHP apps with Phing
Building and Deploying PHP apps with Phing
 
Building and deploying PHP applications with Phing
Building and deploying PHP applications with PhingBuilding and deploying PHP applications with Phing
Building and deploying PHP applications with Phing
 
Deploying PHP applications with Phing
Deploying PHP applications with PhingDeploying PHP applications with Phing
Deploying PHP applications with Phing
 
Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)
 

Dernier

What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 

Dernier (20)

What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 

CQRS & event sourcing in the wild

  • 1. CQRS & EVENT SOURCING IN THE WILD MICHIEL ROOK
  • 2. ➤ Java, PHP & Scala developer ➤ Consultant, trainer, speaker ➤ Dutch Web Alliance ➤ make.io ➤ Maintainer of Phing ➤ @michieltcs
  • 3. YOU
  • 5. heard about CQRS / Event Sourcing RAISE YOUR HAND IF YOU HAVE
  • 6. heard about CQRS / Event Sourcing followed a tutorial, built a hobby project RAISE YOUR HAND IF YOU HAVE
  • 7. heard about CQRS / Event Sourcing followed a tutorial, built a hobby project used it in production RAISE YOUR HAND IF YOU HAVE
  • 8. TOPICS ➤ Quick recap ➤ Replays and rebuilds ➤ Event versioning ➤ Concurrency ➤ Scale
  • 10. ' Event Sourcing ensures that all changes to application state are stored as a sequence of events. -Martin Fowler
  • 11. ACTIVE RECORD VS. EVENT SOURCING Account number Balance 12345678 €€ 50,00 ... ... Money Withdrawn Account number 12345678 Amount €€ 50,00 Money Deposited Account number 12345678 Amount €€ 100,00 Account Created Account number 12345678
  • 12. COMMANDS TO EVENTS Deposit Money Account number 12345678 Amount €€ 100,00 Money Deposited Account number 12345678 Amount €€ 100,00 class DepositMoney {
 public $accountNumber;
 public $amount;
 } class MoneyDeposited {
 public $accountNumber;
 public $amount;
 public $timestamp;
 } function depositMoney(DepositMoney $command) {
 $this->apply(new MoneyDeposited($command->accountNumber,
 $command->amount, date()));
 }
  • 13. AGGREGATES class BankAccount {
 public $accountNumber;
 public $balance;
 
 // command handlers...
 
 public function applyAccountCreated(AccountCreated $event) {
 $this->accountNumber = $event->accountNumber;
 $this->balance = 0;
 }
 
 public function applyMoneyDeposited(MoneyDeposited $event) {
 $this->balance += $event->amount;
 }
 
 public function applyMoneyWithdrawn(MoneyWithdrawn $event) {
 $this->balance -= $event->amount;
 }
 }
  • 14. AGGREGATE STATE Account number Balance 12345678 €€ 0,00 Money Withdrawn Account number 12345678 Amount €€ 50,00 Money Deposited Account number 12345678 Amount €€ 100,00 Account Created Account number 56789012 Account number Balance 12345678 €€ 100,00 Account number Balance 12345678 €€ 50,00
  • 15. CQRS ➤ Command Query Responsibility Segregation ➤ Separate writes (events) and reads (UI) ➤ Optimize for reads!
  • 16. Domain Event Bus Event Handlers Command Repository Data Layer Database Database Event Store commands events events queries DTOs Aggregates
  • 17. PROS AND CONS ➤ Domain fit ➤ Testing ➤ Audit trail ➤ Scalability ➤ Complexity ➤ Library support / maturity
  • 20. PROJECTIONS AND READ MODELS User Registered User Registered User Unregistered Number of active users?
  • 21. PROJECTIONS AND READ MODELS User Registered User Deactivated User Reactivated Number of active users? User Registered User Unregistered
  • 22. PROJECTIONS AND READ MODELS User Registered Event Handler Number of active users +1 User Unregistered Event Handler Number of active users -1
  • 23. PROJECTIONS AND READ MODELS Events Event Handler(s) Storage
  • 24. ELASTICSEARCH class CompanyRegistered {
 public $companyId;
 public $name;
 public $street;
 public $city;
 }
 
 function handleCompanyRegistered(CompanyRegistered $event) {
 $this->elasticsearch->index([
 'index' => 'companies',
 'type' => 'company',
 'id' => $event->companyId,
 'body' => [
 'name' => $event->name,
 'address' => [
 'street' => $event->street,
 'city' => $event->city
 ]
 ]
 ]);
 }
  • 25. READ MODEL UPDATES ➤ New type ➤ New structure ➤ Based on existing events ➤ Generate from scratch?
  • 27. ZERO DOWNTIME Loop over existing events Apply to new read model Apply queued events Start using new read model New events Queue
  • 28. ELASTICSEARCH: MAPPING CHANGE Create index with new mapping Reindex existing documents Apply queued events Start using new index New events Queue
  • 29. CHALLENGE: LONG RUNNING REBUILDS ➤ Alternatives ➤ Distributed ➤ In memory ➤ Partial ➤ Background
  • 30. CHALLENGE: SIDE EFFECTS User Registered User Id 123abc Email Address test@example.net Event Handler Exclude during replays!
  • 31. CHALLENGE: TRANSACTIONS Event Handler Event Handler Event Event Handler Event Handler ?
  • 32. CHALLENGE: EVENTUAL CONSISTENCY ➤ Asynchronous event handlers ➤ Reads eventually return the same value ➤ Compare with ACID
  • 34. DILEMMA ➤ New business requirements ➤ Refactoring ➤ New view on events
  • 35. NEW EVENTS / VERSIONS ➤ No longer relevant ➤ Renamed ➤ Additional or renamed field(s) ➤ Too coarse, too fine
  • 36. SUPPORT YOUR LEGACY? ➤ Events are immutable ➤ Correct (incorrect) old events with new events
  • 38. UPCASTING class UserRegistered_V1 {
 public $userId;
 public $name;
 public $timestamp;
 }
 
 class UserRegistered_V2 {
 public $userId;
 public $name;
 public $date;
 }
 
 function upcast($event): array {
 if (!$event instanceof UserRegistered_V1) {
 return [];
 }
 return [
 new UserRegistered_V2($event->userId, $event->name,
 $event->timestamp->format("Y-m-d"))
 ];
 }
  • 39. REWRITING HISTORY Load (subset of) events Deserialize Modify Serialize Save/replace
  • 40. THINGS TO BE AWARE OF Upcasting ➤ Performance ➤ Complexity ➤ Existing projections not automatically updated Rewriting events ➤ Running code that depends on old structure ➤ Breaking serialization ➤ Changing wrong events
  • 42. CONCURRENT COMMANDS Withdraw Money Account number 12345678 Amount €€ 50,00 Deposit Money Account number 12345678 Amount €€ 100,00 ?
  • 43. PESSIMISTIC LOCKING Withdraw Money Account number 12345678 Amount €€ 50,00 Deposit Money Account number 12345678 Amount €€ 100,00 Account number Balance 12345678 €€ 100,00 Account number Balance 12345678 €€ 50,00 wait for lock lock
  • 44. OPTIMISTIC LOCKING Withdraw Money Account number 12345678 Amount €€ 50,00 version 1 Deposit Money Account number 12345678 Amount €€ 100,00 version 1 Account number Balance 12345678 €€ 100,00 version 2 ConcurrencyException
  • 45. SCALE
  • 46. PERFORMANCE ➤ Server ➤ Database ➤ Framework ➤ Language
  • 47. STORAGE ➤ #events ➤ #aggregates ➤ #events_per_aggregate ➤ Serializer ➤ Speed ➤ Payload size ➤ Costs
  • 48. SNAPSHOTS Events 1 Account Created 2 Money Deposited 3 Money Withdrawn 4 Money Deposited SNAPSHOT 5 Money Withdrawn Events 1 Account Created 2 Money Deposited 3 Money Withdrawn 4 Money Deposited 5 Money Withdrawn
  • 49. SHARDING ➤ Aggregate Id, Type, Event Timestamp, ... ➤ Rebalancing ➤ Distribution
  • 50. ARCHIVING EVENTS ➤ Reduce working set ➤ Inactive / deleted aggregates ➤ Historic / irrelevant events ➤ Cheaper storage
  • 51. FRAMEWORK COMPARISON Framework Upcasting Snapshots Replaying Broadway (PHP) No (PR) No (PR) Not in core Prooph (PHP) MessageFactory Yes, triggers on event count Example code, off line Axon (Java/Scala) Upcaster / UpcasterChain Yes, triggers on event count Yes, ReplayingCluster Akka Persistence (Java/Scala) Event Adapter Yes, decided by actor Yes
  • 52. BROADWAY VS PROOPH class TodoItem extends EventSourcedAggregateRoot {
 private $itemId;
 
 public function __construct(PostTodo $command) {
 $this->apply(new TodoPosted($command->getItemId()));
 }
 
 public function getAggregateRootId()
 {
 return $this->itemId;
 }
 
 public function applyTodoPosted(TodoPosted $event) {
 echo "Posted: " . $event->getItemId() . "n";
 }
 }
  • 53. BROADWAY VS PROOPH class TodoItem extends AggregateRoot {
 private $itemId;
 
 public function __construct(PostTodo $command) {
 $this->recordThat(new TodoPosted($command->getItemId()));
 }
 
 protected function aggregateId() {
 return $this->itemId;
 }
 
 public function whenTodoPosted(TodoPosted $event) {
 echo "Posted: " . $event->getItemId() . "n";
 }
 }