SlideShare a Scribd company logo
Event sourcing and CQRS:
Lessons from the trenches
(Bonus: with Blockchain)
David Jiménez Martínez
davigetto@gmail.com
http://www.linkedin.com/in/davjim/
http://github.com/Rydra/
inari.io
●
Assuming certain knowledge of what CQRS
and ES are
●
Based on our experience
●
“What you see and learn is what you
believe”
●
No zealotry. Software development is
more of an art, a craftmanship, than a
science. Your craft will be diferent than
my craft probably.
●
Feedback is a gift which improves your
craft
About this talk...
●
Lead developer/Chief architect @ Inari
●
Created Melange, an OSS infrastructure
messaging library written in python to
create event-driven, distributed
architectures
●
(https://github.com/Rydra/melange)
– Used in 21Buttons (social network with
high concurrency), Inari (insurtech high-
traceability application supported by AI
and blockchain)
●
An ex .NET developer who found love in
Python and DDD
Who am I?
Quick review at concepts
●
CQRS is an architectural pattern coined by Greg Young
– More info: https://martinfowler.com/bliki/CQRS.html
– In fact it is very simple: Commands (state-changing operations) are separated from
queries (retrieve-only operations). They can have a diferent technology stack and
patterns (and they might live in the same monolith if you see it ft, but the concept is
free from any specifc infrastructure implementation).
– My ELI5 explanation: (usually) you have at least two databases, one to write, and one
to read quickly/do searches (which gets updated some time after the other database
gets written).
●
(In the case of Inari, Blockchain and Postgres/Elasticsearch)
CQRS
CQRS
CQRS, a simplifed view
●
Event sourcing is a technique in which, instead of persisting the current state of
an aggregate root, you persist the events that have happened for that aggregate.
●
This concept and its application has MASSIVE implications in terms of
architecture and implementation when refactoring (as we are going to see)
Event sourcing
Event sourcing
●
We were following the Clean Architecture (the architecture proposed by Uncle
Bob)
●
ELI5: Make the use case/interactor the central part of your system and the main
entry point for your domain. From that point forward, and with the help of
dependency injection, you would coordinate your domain
entities/repositories/services, shielding your domain and business rules (the real
value of your application) from volatile details like framework, IO...
Clean architecture
Clean architecture
CLEAN ARCHITECTURE
Event sourcing implementation @ Inari
●
TERRAIN SCOUT:
– Requirement: as an InsurTech, our solution requires high traceabililty and
auditability. Every event, every action needs to be recorded in our platform.
– Requirement: we need to provide an historic of everything that has happened in the
application, for each aggregate root.
– Requirement: Our tech stack is backed up by Blockchain. Blockchain is a
decentralized, IMMUTABLE database, very hard to hack or manipulate (once you
write there you cannot rewrite or delete data).
ES: The objectives of this war
STEWING SAUCE FOR EVENT SOURCING!
ES: The objectives of this war
●
The promised land:
– It could bring us the high traceability and auditability that we need!
– It could help us defne clearly the events of our system (trust me, giving names and
defne the events of our domain was a big challenge). Refer to Event Storming.
– It could help us separate better the diferent aggregate roots of our domain.
– It could help us making migrations easier.
– It could favor the CQS we were looking for (Fine tune performance in both read side
and write side separately)
ES: The treasure we’re hunting
ES: The treasure we’re hunting
What’s the worst that could happen?
●
We were following the Clean Architecture
●
Our interactors: e.g. GetProductInteractor, GetCompanyInteractor,
RejectProductInteractor, AddPaymentInteractor…
●
Our entities were classic OO classes with behaviour (and some events thrown
here and there). Repository pattern to abstract persistence.
●
Storage technologies: blockchain (where we were storing jsons with the data)
and postgres (where we would store the same data and make searches there).
What we were before...
What we were before...
What we were before...
What we were before...
We know our status quo, and we know where we want to be. Let’s design a
strategy!
What we were before...
●
We started with the main, central aggregate of our application: the Product
– The aggregate root should orchestrate all behaviour. And each, every single
state-modifying method must result in one or several event objects
(logic, otherwise we would not be able to reconstitute this object again).
– Every event relevant to the aggregate should have a method to
reconstitute internal data from the event (called mutator)
– NOTE: No need to move every aggregate to be event sourced at once!
Moving to ES: The strategy
– An event-sourced aggregate needs to alter its constructor: it should only
receive a single parameter, the event stream (which is no more than an
array of events with a version number for optimistic concurrency)
– The constructor would then rehydrate the properties of the object
through the events
– Once the aggregate is in position, the repository should also change to be
able to store the events into the blockchain (our event store)
Moving to ES: The strategy
●
Baby steps:
1) First, remodel internally the aggregate without touching the constructor (BIGGEST
step by far)
2) Then, transform blockchain into an event store and save the events into the it (while
still saving the data in the old way)
3) Remodel the constructor to accept an EventStream instead of a list of properties to
fll
4) Change callers
Moving to ES: The tactics
●
Baby steps:
1) First, remodel internally the aggregate without touching the constructor
(BIGGEST step by far)
2) Then, save the events into the blockchain in the form of events while still saving the
data in the old way
3) Remodel the constructor to accept an EventStream instead of a list of properties to
fll.
4) Change callers
Moving to ES: The war
The war: Talk is cheap, show me the code
The war: Talk is cheap, show me the code
●
It forced us, for every state-changing method, to think of a suitable event and
a name for it and make it explicit in our code
●
Great help in expanding our ubiquitous language with new terms and even
realize some design/requirement mistakes
●
The Product entity turned out to be a little more complex and less stream-
lined than before from our POV, (maybe because we are not yet used to that
thing, like a lot of things in life?)
Moving to ES: The war
●
Baby steps:
1) First, remodel internally the aggregate without touching the constructor (BIGGEST
step by far)
2) Then, transform blockchain into an event store and save the events into the it
(while still saving the data in the old way)
3) Remodel the constructor to accept an EventStream instead of a list of properties to
fll.
4) Change callers
Moving to ES: The war
The war: Talk is cheap, show me the code
The war: Talk is cheap, show me the code
●
Save the events into the blockchain in the form of events while still saving the
data in the old way
– We needed to make serializers for each event in the system (serialize the
events to json)
– Still save the data in the old format elsewhere (postgres + a huge horrible
json into another blockchain setup)
– The repository pattern helped us to mask the access to the event store (and
therefore not coupling too much the technology stack with our business
domain)
Moving to ES: The war
●
Baby steps:
1) First, remodel internally the aggregate without touching the constructor (BIGGEST
step by far)
2) Then, transform blockchain into an event store and save the events into the it (while
still saving the data in the old way)
3) Remodel the constructor to accept an EventStream instead of a list of
properties to fll.
4) Change callers
Moving to ES: The tactics
The war: Talk is cheap, show me the code
●
Remodel the constructor to accept an EventStream instead of a list of
properties to fll
– Changing the constructor was easy… the hard part was to change all the callers.
Relied on the Factory method pattern to solve and refactor this
– Unit/Integration testing the aggregate became a little bit diferent. When
constructing it, you build it in terms of the events that happened for it instead of the
value of the properties you want to supply. Once again, we relied on factory methods
to simplify building event sourced aggregates
– For unit testing we added assertions where we would check that a certain/s event/s
were raised
Moving to ES: The war
●
Better domain and ubiquitous language thanks to be able to properly defne good
event names and defne new ones.
●
Better aggregate isolation
●
Free timeline/historic functionality for the aggregate
●
Forced us to think more in terms of Queries and Commands (CQRS). We are slowly
translating and isolating our interactors between commands (which execute
behaviours and write into blockchain) and queries (which we fne-tune and couple it a
bit more to our storage solution to ofer maximum performance)
●
The solution is a bit more complex, but nothing otherworldly once you have the
infrastructure in motion
●
Moving the Product aggregate was a success, so we can continue moving other
aggregates
Aftermath...
●
Yeah, blockchain is immutable. You cannot delete data from it, you cannot
update data… YOU CANNOT DO MIGRATIONS ON IT!
●
What if you want to do a refactor in your source code (like changing property
names of events, create new ones, delete some of them, etc…?)
– We used Protocol Bufers (from Google). Protobuf ofers backwards compatibility
with message serialization (one part of what we needed).
– New data = create scripts to add new events to correct any desynchronizations.
– Yeah, those “correcting events” need to be considered by your aggregate.
●
Other complex techniques: Upcasting
Moving to ES: But… Postwar
●
Performance
– If you have a lot of events for each aggregate… This could hurt performance!
– Snapshots
– For the time being we are not dealing with a huge amount of events per aggregate
(100 at most), so we are surviving the storm for now without snapshooting.
Moving to ES: But… Postwar
●
Not really unless you have either big concurrency (e.g. a social network) or
high traceability and auditability requirements
●
Though it helps a ton in improving the ubiquitous language through the forced
extensive use of events
Would I recommend CQRS + ES?
●
Microservices: one single, central event store vs one event store per service?
– “Should the book of your history be written in a single book or distributed in several
ones?”
– Possible implementations? Is there any silver bullet or are there any good solutions?
Next challenges for Inari
●
Implementing Domain Driven Design (Vaughn Vernon)
●
Clean Architecture (Robert C. Martin)
●
Protocol Bufers vs Apache Thrift (https://es.slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro)
●
Event sourcing versioning (Greg Young) (https://leanpub.com/esversioning)
●
Implementing Event sourcing in Python (
https://breadcrumbscollector.tech/implementing-event-sourcing-in-python-part-1-aggregates/)
●
Event sourcing in Python (https://hackernoon.com/1-year-of-event-sourcing-and-cqrs-fb9033ccd1c6)
●
Clean architecture in Python (https://speakerdeck.com/enforcer/clean-architecture-in-python?slide=30)
●
Melange, a messaging library written in Python to create event driven, distributed applications and
microservices (https://github.com/Rydra/melange)
Bibliography
Event sourcing and CQRS: Lessons from the trenches

More Related Content

Similar to Event sourcing and CQRS: Lessons from the trenches

Ethereum Devcon1 Report (summary writing)
Ethereum Devcon1 Report (summary writing)Ethereum Devcon1 Report (summary writing)
Ethereum Devcon1 Report (summary writing)
Tomoaki Sato
 
Zenko @Cloud Native Foundation London Meetup March 6th 2018
Zenko @Cloud Native Foundation London Meetup March 6th 2018Zenko @Cloud Native Foundation London Meetup March 6th 2018
Zenko @Cloud Native Foundation London Meetup March 6th 2018
Laure Vergeron
 
Blockchain Experiments 1-11.pptx
Blockchain Experiments 1-11.pptxBlockchain Experiments 1-11.pptx
Blockchain Experiments 1-11.pptx
saiproject
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
Matthias Noback
 
Data Science in the Cloud @StitchFix
Data Science in the Cloud @StitchFixData Science in the Cloud @StitchFix
Data Science in the Cloud @StitchFix
C4Media
 
Introduction to Blockchain Development
Introduction to Blockchain DevelopmentIntroduction to Blockchain Development
Introduction to Blockchain Development
Lightstreams
 
Deconstructing Monoliths with Domain Driven Design
Deconstructing Monoliths with Domain Driven DesignDeconstructing Monoliths with Domain Driven Design
Deconstructing Monoliths with Domain Driven Design
VMware Tanzu
 
Implementing Event Sourcing in .NET
Implementing Event Sourcing in .NETImplementing Event Sourcing in .NET
Implementing Event Sourcing in .NET
Andrea Saltarello
 
Brownfield Domain Driven Design
Brownfield Domain Driven DesignBrownfield Domain Driven Design
Brownfield Domain Driven Design
Nicolò Pignatelli
 
How it's made - MyGet (CloudBurst)
How it's made - MyGet (CloudBurst)How it's made - MyGet (CloudBurst)
How it's made - MyGet (CloudBurst)
Maarten Balliauw
 
Evolving your api architecture with the strangler pattern
Evolving your api architecture with the strangler patternEvolving your api architecture with the strangler pattern
Evolving your api architecture with the strangler pattern
dwcarter74
 
MongoDB.local Austin 2018: Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...
MongoDB.local Austin 2018:  Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...MongoDB.local Austin 2018:  Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...
MongoDB.local Austin 2018: Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...
MongoDB
 
Blockchain Introduction
Blockchain IntroductionBlockchain Introduction
Blockchain Introduction
Nur Aini Rakhmawati Gunawan
 
Azure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
Azure tales: a real world CQRS and ES Deep Dive - Andrea SaltarelloAzure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
Azure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
ITCamp
 
Domain driven design: a gentle introduction
Domain driven design:  a gentle introductionDomain driven design:  a gentle introduction
Domain driven design: a gentle introduction
Asher Sterkin
 
Building Reactive Real-time Data Pipeline
Building Reactive Real-time Data PipelineBuilding Reactive Real-time Data Pipeline
Building Reactive Real-time Data Pipeline
Trieu Nguyen
 
Predicting Space Weather with Docker
Predicting Space Weather with DockerPredicting Space Weather with Docker
Predicting Space Weather with Docker
Docker, Inc.
 
Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...
Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...
Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...
HostedbyConfluent
 
Code Refactoring or Rewrite: How to Properly Dispose of Legacy Code
Code Refactoring or Rewrite: How to Properly Dispose of Legacy CodeCode Refactoring or Rewrite: How to Properly Dispose of Legacy Code
Code Refactoring or Rewrite: How to Properly Dispose of Legacy Code
Roman Labunsky
 
Kubernetes in 15 minutes
Kubernetes in 15 minutesKubernetes in 15 minutes
Kubernetes in 15 minutes
rhirschfeld
 

Similar to Event sourcing and CQRS: Lessons from the trenches (20)

Ethereum Devcon1 Report (summary writing)
Ethereum Devcon1 Report (summary writing)Ethereum Devcon1 Report (summary writing)
Ethereum Devcon1 Report (summary writing)
 
Zenko @Cloud Native Foundation London Meetup March 6th 2018
Zenko @Cloud Native Foundation London Meetup March 6th 2018Zenko @Cloud Native Foundation London Meetup March 6th 2018
Zenko @Cloud Native Foundation London Meetup March 6th 2018
 
Blockchain Experiments 1-11.pptx
Blockchain Experiments 1-11.pptxBlockchain Experiments 1-11.pptx
Blockchain Experiments 1-11.pptx
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
Data Science in the Cloud @StitchFix
Data Science in the Cloud @StitchFixData Science in the Cloud @StitchFix
Data Science in the Cloud @StitchFix
 
Introduction to Blockchain Development
Introduction to Blockchain DevelopmentIntroduction to Blockchain Development
Introduction to Blockchain Development
 
Deconstructing Monoliths with Domain Driven Design
Deconstructing Monoliths with Domain Driven DesignDeconstructing Monoliths with Domain Driven Design
Deconstructing Monoliths with Domain Driven Design
 
Implementing Event Sourcing in .NET
Implementing Event Sourcing in .NETImplementing Event Sourcing in .NET
Implementing Event Sourcing in .NET
 
Brownfield Domain Driven Design
Brownfield Domain Driven DesignBrownfield Domain Driven Design
Brownfield Domain Driven Design
 
How it's made - MyGet (CloudBurst)
How it's made - MyGet (CloudBurst)How it's made - MyGet (CloudBurst)
How it's made - MyGet (CloudBurst)
 
Evolving your api architecture with the strangler pattern
Evolving your api architecture with the strangler patternEvolving your api architecture with the strangler pattern
Evolving your api architecture with the strangler pattern
 
MongoDB.local Austin 2018: Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...
MongoDB.local Austin 2018:  Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...MongoDB.local Austin 2018:  Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...
MongoDB.local Austin 2018: Ch-Ch-Ch-Ch-Changes: Taking Your MongoDB Stitch A...
 
Blockchain Introduction
Blockchain IntroductionBlockchain Introduction
Blockchain Introduction
 
Azure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
Azure tales: a real world CQRS and ES Deep Dive - Andrea SaltarelloAzure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
Azure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
 
Domain driven design: a gentle introduction
Domain driven design:  a gentle introductionDomain driven design:  a gentle introduction
Domain driven design: a gentle introduction
 
Building Reactive Real-time Data Pipeline
Building Reactive Real-time Data PipelineBuilding Reactive Real-time Data Pipeline
Building Reactive Real-time Data Pipeline
 
Predicting Space Weather with Docker
Predicting Space Weather with DockerPredicting Space Weather with Docker
Predicting Space Weather with Docker
 
Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...
Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...
Next Gen Data Modeling in the Open Data Platform With Doron Porat and Liran Y...
 
Code Refactoring or Rewrite: How to Properly Dispose of Legacy Code
Code Refactoring or Rewrite: How to Properly Dispose of Legacy CodeCode Refactoring or Rewrite: How to Properly Dispose of Legacy Code
Code Refactoring or Rewrite: How to Properly Dispose of Legacy Code
 
Kubernetes in 15 minutes
Kubernetes in 15 minutesKubernetes in 15 minutes
Kubernetes in 15 minutes
 

Recently uploaded

LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
lorraineandreiamcidl
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
Hornet Dynamics
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
Gerardo Pardo-Castellote
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
Peter Muessig
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
rodomar2
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 

Recently uploaded (20)

LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 

Event sourcing and CQRS: Lessons from the trenches

  • 1. Event sourcing and CQRS: Lessons from the trenches (Bonus: with Blockchain) David Jiménez Martínez davigetto@gmail.com http://www.linkedin.com/in/davjim/ http://github.com/Rydra/ inari.io
  • 2. ● Assuming certain knowledge of what CQRS and ES are ● Based on our experience ● “What you see and learn is what you believe” ● No zealotry. Software development is more of an art, a craftmanship, than a science. Your craft will be diferent than my craft probably. ● Feedback is a gift which improves your craft About this talk...
  • 3. ● Lead developer/Chief architect @ Inari ● Created Melange, an OSS infrastructure messaging library written in python to create event-driven, distributed architectures ● (https://github.com/Rydra/melange) – Used in 21Buttons (social network with high concurrency), Inari (insurtech high- traceability application supported by AI and blockchain) ● An ex .NET developer who found love in Python and DDD Who am I?
  • 4. Quick review at concepts
  • 5. ● CQRS is an architectural pattern coined by Greg Young – More info: https://martinfowler.com/bliki/CQRS.html – In fact it is very simple: Commands (state-changing operations) are separated from queries (retrieve-only operations). They can have a diferent technology stack and patterns (and they might live in the same monolith if you see it ft, but the concept is free from any specifc infrastructure implementation). – My ELI5 explanation: (usually) you have at least two databases, one to write, and one to read quickly/do searches (which gets updated some time after the other database gets written). ● (In the case of Inari, Blockchain and Postgres/Elasticsearch) CQRS
  • 7. ● Event sourcing is a technique in which, instead of persisting the current state of an aggregate root, you persist the events that have happened for that aggregate. ● This concept and its application has MASSIVE implications in terms of architecture and implementation when refactoring (as we are going to see) Event sourcing
  • 9. ● We were following the Clean Architecture (the architecture proposed by Uncle Bob) ● ELI5: Make the use case/interactor the central part of your system and the main entry point for your domain. From that point forward, and with the help of dependency injection, you would coordinate your domain entities/repositories/services, shielding your domain and business rules (the real value of your application) from volatile details like framework, IO... Clean architecture
  • 12. ● TERRAIN SCOUT: – Requirement: as an InsurTech, our solution requires high traceabililty and auditability. Every event, every action needs to be recorded in our platform. – Requirement: we need to provide an historic of everything that has happened in the application, for each aggregate root. – Requirement: Our tech stack is backed up by Blockchain. Blockchain is a decentralized, IMMUTABLE database, very hard to hack or manipulate (once you write there you cannot rewrite or delete data). ES: The objectives of this war
  • 13. STEWING SAUCE FOR EVENT SOURCING! ES: The objectives of this war
  • 14. ● The promised land: – It could bring us the high traceability and auditability that we need! – It could help us defne clearly the events of our system (trust me, giving names and defne the events of our domain was a big challenge). Refer to Event Storming. – It could help us separate better the diferent aggregate roots of our domain. – It could help us making migrations easier. – It could favor the CQS we were looking for (Fine tune performance in both read side and write side separately) ES: The treasure we’re hunting
  • 15. ES: The treasure we’re hunting
  • 16. What’s the worst that could happen?
  • 17. ● We were following the Clean Architecture ● Our interactors: e.g. GetProductInteractor, GetCompanyInteractor, RejectProductInteractor, AddPaymentInteractor… ● Our entities were classic OO classes with behaviour (and some events thrown here and there). Repository pattern to abstract persistence. ● Storage technologies: blockchain (where we were storing jsons with the data) and postgres (where we would store the same data and make searches there). What we were before...
  • 18. What we were before...
  • 19. What we were before...
  • 20. What we were before...
  • 21. We know our status quo, and we know where we want to be. Let’s design a strategy! What we were before...
  • 22. ● We started with the main, central aggregate of our application: the Product – The aggregate root should orchestrate all behaviour. And each, every single state-modifying method must result in one or several event objects (logic, otherwise we would not be able to reconstitute this object again). – Every event relevant to the aggregate should have a method to reconstitute internal data from the event (called mutator) – NOTE: No need to move every aggregate to be event sourced at once! Moving to ES: The strategy
  • 23. – An event-sourced aggregate needs to alter its constructor: it should only receive a single parameter, the event stream (which is no more than an array of events with a version number for optimistic concurrency) – The constructor would then rehydrate the properties of the object through the events – Once the aggregate is in position, the repository should also change to be able to store the events into the blockchain (our event store) Moving to ES: The strategy
  • 24. ● Baby steps: 1) First, remodel internally the aggregate without touching the constructor (BIGGEST step by far) 2) Then, transform blockchain into an event store and save the events into the it (while still saving the data in the old way) 3) Remodel the constructor to accept an EventStream instead of a list of properties to fll 4) Change callers Moving to ES: The tactics
  • 25. ● Baby steps: 1) First, remodel internally the aggregate without touching the constructor (BIGGEST step by far) 2) Then, save the events into the blockchain in the form of events while still saving the data in the old way 3) Remodel the constructor to accept an EventStream instead of a list of properties to fll. 4) Change callers Moving to ES: The war
  • 26. The war: Talk is cheap, show me the code
  • 27. The war: Talk is cheap, show me the code
  • 28. ● It forced us, for every state-changing method, to think of a suitable event and a name for it and make it explicit in our code ● Great help in expanding our ubiquitous language with new terms and even realize some design/requirement mistakes ● The Product entity turned out to be a little more complex and less stream- lined than before from our POV, (maybe because we are not yet used to that thing, like a lot of things in life?) Moving to ES: The war
  • 29. ● Baby steps: 1) First, remodel internally the aggregate without touching the constructor (BIGGEST step by far) 2) Then, transform blockchain into an event store and save the events into the it (while still saving the data in the old way) 3) Remodel the constructor to accept an EventStream instead of a list of properties to fll. 4) Change callers Moving to ES: The war
  • 30. The war: Talk is cheap, show me the code
  • 31. The war: Talk is cheap, show me the code
  • 32. ● Save the events into the blockchain in the form of events while still saving the data in the old way – We needed to make serializers for each event in the system (serialize the events to json) – Still save the data in the old format elsewhere (postgres + a huge horrible json into another blockchain setup) – The repository pattern helped us to mask the access to the event store (and therefore not coupling too much the technology stack with our business domain) Moving to ES: The war
  • 33. ● Baby steps: 1) First, remodel internally the aggregate without touching the constructor (BIGGEST step by far) 2) Then, transform blockchain into an event store and save the events into the it (while still saving the data in the old way) 3) Remodel the constructor to accept an EventStream instead of a list of properties to fll. 4) Change callers Moving to ES: The tactics
  • 34. The war: Talk is cheap, show me the code
  • 35. ● Remodel the constructor to accept an EventStream instead of a list of properties to fll – Changing the constructor was easy… the hard part was to change all the callers. Relied on the Factory method pattern to solve and refactor this – Unit/Integration testing the aggregate became a little bit diferent. When constructing it, you build it in terms of the events that happened for it instead of the value of the properties you want to supply. Once again, we relied on factory methods to simplify building event sourced aggregates – For unit testing we added assertions where we would check that a certain/s event/s were raised Moving to ES: The war
  • 36. ● Better domain and ubiquitous language thanks to be able to properly defne good event names and defne new ones. ● Better aggregate isolation ● Free timeline/historic functionality for the aggregate ● Forced us to think more in terms of Queries and Commands (CQRS). We are slowly translating and isolating our interactors between commands (which execute behaviours and write into blockchain) and queries (which we fne-tune and couple it a bit more to our storage solution to ofer maximum performance) ● The solution is a bit more complex, but nothing otherworldly once you have the infrastructure in motion ● Moving the Product aggregate was a success, so we can continue moving other aggregates Aftermath...
  • 37. ● Yeah, blockchain is immutable. You cannot delete data from it, you cannot update data… YOU CANNOT DO MIGRATIONS ON IT! ● What if you want to do a refactor in your source code (like changing property names of events, create new ones, delete some of them, etc…?) – We used Protocol Bufers (from Google). Protobuf ofers backwards compatibility with message serialization (one part of what we needed). – New data = create scripts to add new events to correct any desynchronizations. – Yeah, those “correcting events” need to be considered by your aggregate. ● Other complex techniques: Upcasting Moving to ES: But… Postwar
  • 38. ● Performance – If you have a lot of events for each aggregate… This could hurt performance! – Snapshots – For the time being we are not dealing with a huge amount of events per aggregate (100 at most), so we are surviving the storm for now without snapshooting. Moving to ES: But… Postwar
  • 39. ● Not really unless you have either big concurrency (e.g. a social network) or high traceability and auditability requirements ● Though it helps a ton in improving the ubiquitous language through the forced extensive use of events Would I recommend CQRS + ES?
  • 40. ● Microservices: one single, central event store vs one event store per service? – “Should the book of your history be written in a single book or distributed in several ones?” – Possible implementations? Is there any silver bullet or are there any good solutions? Next challenges for Inari
  • 41. ● Implementing Domain Driven Design (Vaughn Vernon) ● Clean Architecture (Robert C. Martin) ● Protocol Bufers vs Apache Thrift (https://es.slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro) ● Event sourcing versioning (Greg Young) (https://leanpub.com/esversioning) ● Implementing Event sourcing in Python ( https://breadcrumbscollector.tech/implementing-event-sourcing-in-python-part-1-aggregates/) ● Event sourcing in Python (https://hackernoon.com/1-year-of-event-sourcing-and-cqrs-fb9033ccd1c6) ● Clean architecture in Python (https://speakerdeck.com/enforcer/clean-architecture-in-python?slide=30) ● Melange, a messaging library written in Python to create event driven, distributed applications and microservices (https://github.com/Rydra/melange) Bibliography