SlideShare a Scribd company logo
1 of 62
CQRS / ES
by Vic Metcalfe / @v_metcalfe
Command / Query
Responsibility
Segregation, Event
Sourcing and a little
Domain Driven Design
Welcome
• Not an expert
• Over 60 slides, many containing code
• Ask questions at any time, expect short
answers / discussion
• Q & A after 30 minutes, or talk to me after
CRUD
CREATE / REPORT /
UPDATE / DELETE
UPDATE AND
DELETE DESTROY
DATA
HOW MUCH WAS
THAT DATA WORTH?
Treat the storage of
data as a separate
problem from the
retrieval of data
THE RIGHT WAY
THE RIGHT WAY
Everything you
need to know
about Event
Sourcing, you
can learn from
git
accounting
or
Why so
difficult?
CQRS
DDDES
Domain Driven
Design
• Helps business stakeholders think about their
requirements
• Helps developers adapt their software models
to the problem domain
DDD Strategies
• BDD (Behaviour Driven Development)
• CI (Continuous Integration)
• DTO (Data Transfer Object)
• Bounded Contexts
• Domain Events / Event Storming
• CQRS / ES
• …more!
Command /
Query
Responsibility
Segregation
CQRS naturally emerged from DDD
Read
Models
Write
Models
Emerge naturally from
events
Emerge naturally from
how we use our data
Event Sourcing
ES naturally emerged from CQRS
The Event Store is TRUTH
Working
Definitions
• Command
• Event
• Aggregate
• Aggregate Root
Command Communicates an INTENT to change the
application’s state
Event Records the FACT that a thing happened that
changed the application’s state
Aggregate A data model that is built up by the events that
contributed to it’s state
Aggregate Root
An aggregate that has a unique identifier.
It may contain:
• Other aggregates
• References to other aggregate roots
Command Events
function command($parameters)
{
if (!$this-validateParams($parameters))
{
throw new InvariantException();
}
// Determine resulting events
return [ $event, $anotherEvent ];
}
Discussion
Points
• Where should we place our commands?
• Can commands say no?
• Distributed systems and CQRS
Events Aggregate
/** @Apply(User::SOME_EVENT) */
protected function didSomething($id, $payload)
{
$this->field = $payload['key'];
}
Discussion
Points
• Annotations?
• Where should we place apply methods?
• Why pass both ID and payload?
Event Projections
/**
* @Projector(Aggregate::SOME_EVENT)
*/
function onSomeEvent($id, Event $event)
{
// Update read model(s)
}
Discussion
Points
• Where should we place projectors?
• Should projections live in the same database
as our events?
• Batch and asynchronous projections
Event
Process
Manager
Commands
/**
* @ProcessManager (ProcessManager::SOME_EVENT)
*/
function onSomeEvent($id, Event $event)
{
// Invoke some command(s)
}
Discussion
Points
• Where should we place process managers?
• They look like projectors – why do we need
both?
• Why not just have process managers create
events directly?
Working
Definitions
• Event Stream
• Invariant
• Ubiquitous Language
• Bounded Context
• Snapshots
Event Stream An ordered list of events for a specific aggregate
root
Invariant
• Business Rule
• Enforced by Commands
Ubiquitous
Language
• Definitions that have specialized meaning
within our problem domain
• Updated as needed when terminology evolves
in a project team
Bounded
Context
• A specific problem domain
• A project may contain just one or many
• An aggregate is defined within a single
bounded context
Snapshots
• Specialized projections that capture an
aggregate root at a specific version
• Load from snapshot and update from events
Concurrency
Aggregate
Root
Command
Events
Record
Start over
on version
mismatch
Load an aggregate root
before initiating a
command for it
Concurrency
Aggregate
Root
Command
Events
Record
Start over
on version
mismatch
Command enforces
invariants based on a
specific version of the
aggregate root
Concurrency
Aggregate
Root
Command
Events
Record
Start over
on version
mismatch
Command generated
events which will be
recorded into an event
stream.
Concurrency
Aggregate
Root
Command
Events
Record
Start over
on version
mismatch
Events (and maybe
some projections) are
recorded in a single
transaction so they are
all recorded, or none
are recorded
Concurrency
Aggregate
Root
Command
Events
Record
Start over
on version
mismatch
If the current version
isn’t the same one the
command acted on,
throw out the events
and retry a few times.
Reliability
• The impact of bugs is reduced by the
immutability of event streams
• Lower complexity* makes bugs less likely and
code easier to test
* Assuming our application is non-trivial and that CQRS/ES results in
lower complexity!
Flexibility
• Separation of concerns
• Tends to be implemented in short simple
functions, or small simple classes
• “If we’d recorded that in the database it
wouldn’t be a problem”
• “That report will be slow because of too many
joins”
Scaling
• Different aggregate root types can use
different event stores / databases
• Projections can live on different databases
• Projections can use the most appropriate
database technology (relational, no-SQL,
graph, etc.…)
Security
• Event store can be read and append only
• Projections can be audited
• Web application can have read-only rights to
projections
Concrete
Example
• User Registration
• Email Confirmation
• One projection; one process manager
Feature: Register a new client
So that I can borrow books, as a guest I need to create an account on the system.
Background:
Given that I am a guest on the registration page
And I have filled in "pat@example.com" for my email address
And I have filled in "letmein" for my password
Scenario: Register a new Client
When I click the register button
Then I receive an email to "pat@example.com" asking me to confirm my email address
And my password is "letmein"
Scenario: Confirm Email Address
Given I click the register button
And I receive a confirmation email
When I follow the link in the confirmation email
Then my account is confirmed
/**
* @When /^I click the register button$/
*/
public function iClickTheRegisterButton()
{
try {
list($id, $token) = explode(';', $this->emailConfirmationToken);
$this->streamManager->recordCommand(
1,
[$this->userCommands, 'register'],
1, $this->registrationForm['email'], $this->registrationForm['password'], $token
);
} catch (Exception $e) {
$this->lastException = $e;
}
}
features/bootstrap/UserContext.php
Record
Command
Aggregate
Root
Command
Events
Record
Start over
on version
mismatch
The record command
call on the last page
looks like this inside
public function register($user, $id, $email, $hashedPassword, $token)
{
if (!is_null($user)) {
throw new InvariantException("Only new users can register. " .
"User $id has already been registered.");
}
$stmt = $this->db->prepare("select id from user where confirmed_email=:email");
$stmt->execute(['email'=>$email]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row !== false) {
throw new EmailAlreadyRegisteredException();
}
Projection
src/Model/User/UserCommands.php
$stmt = $this->db->prepare("select id from user where requested_email=:email");
$stmt->execute(['email'=>$email]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row !== false) {
throw new EmailAlreadyPendingException();
}
return Event::NamedPayloadPairsToArray(
User::REGISTERED, [],
User::PROVIDED_EMAIL_ADDRESS, ['email' => $email, 'token'=>$token],
User::CHANGED_PASSWORD, ['password'=>$hashedPassword]
);
Projection
src/Model/User/UserCommands.php
There’s a much better way to enforce unique emails by using a
separate aggregate root with email keys and Associate /
Disassociate commands, but that wouldn’t fit into a ½ hour talk!
/** @Apply(User::REGISTERED) */
protected function registered($id)
{
$this->id = $id;
}
/** @Apply(User::PROVIDED_EMAIL_ADDRESS) */
protected function providedEmailAddress($id, $payload)
{
$this->email = $payload['email'];
$this->emailConfirmationToken = $payload['token'];
}
/** @Apply(User::CHANGED_PASSWORD) */
protected function changedPassword($id, $payload)
{
$this->password = password_hash($payload['password'], PASSWORD_DEFAULT);
} src/Model/User/User.php
/** @Projector(User::REGISTERED) */
public function OnRegistered($id)
{
$stmt = $this->connection->prepare("insert into user (id) values (:id)");
$stmt->execute(['id'=>$id]);
}
src/Model/User/Projector/UserListProjector.php
/** @Projector(User::PROVIDED_EMAIL_ADDRESS) */
public function OnProvidedEmailAddress($id, Event $event)
{
$payload = $event->getPayload();
$stmt = $this->connection->prepare(
"update user set requested_email=:email where id=:id");
$stmt->execute(['id'=>$id, 'email'=>$payload['email']]);
}
src/Model/User/Projector/UserListProjector.php
/** @Projector(User::CHANGED_PASSWORD) */
public function OnChangedPassword($id, Event $event)
{
$payload = $event->getPayload();
$stmt = $this->connection->prepare(
"update user set password=:password where id=:id");
$stmt->execute(['id'=>$id, 'password'=>$payload['password']]);
}
src/Model/User/Projector/UserListProjector.php
/** @ProcessManager(User::PROVIDED_EMAIL_ADDRESS) */
public function providedEmailAddress($id, Event $event)
{
$payload = $event->getPayload();
$this->stream->recordCommand(
$id,
[$this->userCommands, 'sendEmailConfirmationMessage'],
$payload['email'], $id
);
}
src/Model/User/ProcessManager/SendEmailConfirmation.php
src/Model/User/UserCommands.php
public function sendEmailConfirmationMessage(User $user, $email, $id)
{
$confirmationCode = $user->getEmailConfirmationToken();
$message = (new Swift_Message("Please confirm your email address"))
->addTo($email)
->addFrom($this->confirmationFrom)
->setBody("Please confirm your email with $id;$confirmationCode.")
;
$this->mailer->send($message);
return Event::NamedPayloadPairsToArray(User::SENT_CONFIRMATION);
}
features/bootstrap/UserContext.php
/**
* @When /^I follow the link in the confirmation email$/
*/
public function iFollowTheLink()
{
list($id, $token) = explode(';', $this->emailConfirmationToken);
$this->streamManager->recordCommand($id,
[$this->userCommands, 'confirmEmail'],
$token
);
}
src/Model/User/UserCommands.php
public function confirmEmail(User $user, $token)
{
if (!$user->matchEmailConfirmationToken($token)) {
return []; //Like nothing happened, for now we will ignore failed attempts
}
return Event::NamedPayloadPairsToArray(User::CONFIRMED_EMAIL);
}
src/Model/User/User.php
/** @Apply(User::CONFIRMED_EMAIL) */
protected function confirmedEmail()
{
$this->confirmedEmail = true;
}
src/Model/User/Projector/UserListProjector.php
/** @Projector(User::CONFIRMED_EMAIL) */
public function OnConfirmedEmail($id)
{
$sql = "update user set confirmed_email = requested_email where id=:id";
$stmt = $this->connection->prepare($sql);
$stmt->execute(['id'=>$id]);
}
Future State
• Temporal “what if” queries
• Offline Events – mobile
• Ephemeral Event Stores for temporary state
• Greater adoption of non-distributed CQRS
Resources
• Domain Driven Design Quickly
• https://www.infoq.com/minibooks/domain-driven-design-quickly
• Head First Domain Driven Design
• http://headfirstdomaindrivendesign.com/
• Prooph – CQRS for PHP
• http://getprooph.org/
• CQRS Journey by Microsoft
• https://docs.microsoft.com/en-us/previous-versions/msp-n-p/jj554200(v=pandp.10)
Thank you!
• Wrap up
• Q & A

More Related Content

What's hot

clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionsaber tabatabaee
 
CQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDDCQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDDDennis Doomen
 
Clean Code - The Next Chapter
Clean Code - The Next ChapterClean Code - The Next Chapter
Clean Code - The Next ChapterVictor Rentea
 
Clean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflixClean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflixVictor Rentea
 
CSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVCCSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVCSuvash Shah
 
WAF Bypass Techniques - Using HTTP Standard and Web Servers’ Behaviour
WAF Bypass Techniques - Using HTTP Standard and Web Servers’ BehaviourWAF Bypass Techniques - Using HTTP Standard and Web Servers’ Behaviour
WAF Bypass Techniques - Using HTTP Standard and Web Servers’ BehaviourSoroush Dalili
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Steve Pember
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
 
Messaging With ActiveMQ
Messaging With ActiveMQMessaging With ActiveMQ
Messaging With ActiveMQBruce Snyder
 
Railway Orientated Programming In C#
Railway Orientated Programming In C#Railway Orientated Programming In C#
Railway Orientated Programming In C#Tama000
 
The Art of Discovering Bounded Contexts
The Art of Discovering Bounded ContextsThe Art of Discovering Bounded Contexts
The Art of Discovering Bounded ContextsNick Tune
 
Cross site scripting attacks and defenses
Cross site scripting attacks and defensesCross site scripting attacks and defenses
Cross site scripting attacks and defensesMohammed A. Imran
 
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015CODE BLUE
 

What's hot (20)

clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English version
 
Clean code slide
Clean code slideClean code slide
Clean code slide
 
Clean code
Clean codeClean code
Clean code
 
Clean Code
Clean CodeClean Code
Clean Code
 
CQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDDCQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDD
 
Clean Code - The Next Chapter
Clean Code - The Next ChapterClean Code - The Next Chapter
Clean Code - The Next Chapter
 
Clean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflixClean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflix
 
CSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVCCSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVC
 
WAF Bypass Techniques - Using HTTP Standard and Web Servers’ Behaviour
WAF Bypass Techniques - Using HTTP Standard and Web Servers’ BehaviourWAF Bypass Techniques - Using HTTP Standard and Web Servers’ Behaviour
WAF Bypass Techniques - Using HTTP Standard and Web Servers’ Behaviour
 
Clean code
Clean codeClean code
Clean code
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
 
Clean code
Clean codeClean code
Clean code
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
Messaging With ActiveMQ
Messaging With ActiveMQMessaging With ActiveMQ
Messaging With ActiveMQ
 
Railway Orientated Programming In C#
Railway Orientated Programming In C#Railway Orientated Programming In C#
Railway Orientated Programming In C#
 
Clean Code
Clean CodeClean Code
Clean Code
 
The Art of Discovering Bounded Contexts
The Art of Discovering Bounded ContextsThe Art of Discovering Bounded Contexts
The Art of Discovering Bounded Contexts
 
Clean code
Clean code Clean code
Clean code
 
Cross site scripting attacks and defenses
Cross site scripting attacks and defensesCross site scripting attacks and defenses
Cross site scripting attacks and defenses
 
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
 

Similar to CQRS / ES & DDD Demystified

540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdfhamzadamani7
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsSalesforce Developers
 
SplunkApplicationLoggingBestPractices_Template_2.3.pdf
SplunkApplicationLoggingBestPractices_Template_2.3.pdfSplunkApplicationLoggingBestPractices_Template_2.3.pdf
SplunkApplicationLoggingBestPractices_Template_2.3.pdfTuynNguyn819213
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin Cataldo
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup PerformanceGreg Whalin
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
How to generate customized java 8 code from your database
How to generate customized java 8 code from your databaseHow to generate customized java 8 code from your database
How to generate customized java 8 code from your databaseSpeedment, Inc.
 
Silicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your databaseSilicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your databaseSpeedment, Inc.
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Decomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDecomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDennis Doomen
 
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...CodeMill digital skills
 
Cqrs and event sourcing in azure
Cqrs and event sourcing in azureCqrs and event sourcing in azure
Cqrs and event sourcing in azureSergey Seletsky
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
SOUG_Deployment__Automation_DB
SOUG_Deployment__Automation_DBSOUG_Deployment__Automation_DB
SOUG_Deployment__Automation_DBUniFabric
 
2015 ZendCon - Do you queue
2015 ZendCon - Do you queue2015 ZendCon - Do you queue
2015 ZendCon - Do you queueMike Willbanks
 
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"Andrii Dembitskyi "Events in our applications Event bus and distributed systems"
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"Fwdays
 

Similar to CQRS / ES & DDD Demystified (20)

540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong Foundations
 
SplunkApplicationLoggingBestPractices_Template_2.3.pdf
SplunkApplicationLoggingBestPractices_Template_2.3.pdfSplunkApplicationLoggingBestPractices_Template_2.3.pdf
SplunkApplicationLoggingBestPractices_Template_2.3.pdf
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup Performance
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup Performance
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
How to generate customized java 8 code from your database
How to generate customized java 8 code from your databaseHow to generate customized java 8 code from your database
How to generate customized java 8 code from your database
 
Silicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your databaseSilicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your database
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Decomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDecomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservices
 
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
 
Cqrs and event sourcing in azure
Cqrs and event sourcing in azureCqrs and event sourcing in azure
Cqrs and event sourcing in azure
 
Codegnitorppt
CodegnitorpptCodegnitorppt
Codegnitorppt
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
SOUG_Deployment__Automation_DB
SOUG_Deployment__Automation_DBSOUG_Deployment__Automation_DB
SOUG_Deployment__Automation_DB
 
Ruby For Startups
Ruby For StartupsRuby For Startups
Ruby For Startups
 
2015 ZendCon - Do you queue
2015 ZendCon - Do you queue2015 ZendCon - Do you queue
2015 ZendCon - Do you queue
 
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"Andrii Dembitskyi "Events in our applications Event bus and distributed systems"
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"
 

Recently uploaded

Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVRajaP95
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxJoão Esperancinha
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)Suman Mia
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Dr.Costas Sachpazis
 
main PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfidmain PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfidNikhilNagaraju
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile servicerehmti665
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escortsranjana rawat
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )Tsuyoshi Horigome
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
GDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSCAESB
 

Recently uploaded (20)

Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCRCall Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
main PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfidmain PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfid
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile service
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
GDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentation
 

CQRS / ES & DDD Demystified

Editor's Notes

  1. In this example commands return events and throw errors. These things could also have been accomplished many other ways.
  2. We usually need the payload. The ID is really only needed for the event that initiates a new aggregate root, but is passed to all of them in my implantation for consistency.
  3. Projections that need to be transactionally included in a recording need to be in the same storage as the event store used.
  4. The 1 here is the client generated ID. Normally this would be a UUID4. It is passed in twice, once as the first parameter to recordCommand() and again as the first parameter to the register command.
  5. Constants (User::REGISTERED, etc) are the event names that will be recorded in the event store. The names of the constants can change to reflect the ubiquitous language, but the stored event names can’t be changed. Assuming a unique constraint on the confirmed_email column this might throw an exception, the transaction will roll back and the application will have to deal with it. There is a better way that involves another aggregate root with email identifiers and associate / disassociate commands, but that would be too much to get into in a ½ hour talk!