SlideShare a Scribd company logo
1 of 42
Download to read offline
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 with Blockchain

More Related Content

Similar to Event Sourcing and CQRS Lessons from the Trenches with Blockchain

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 2018Laure Vergeron
 
Blockchain Experiments 1-11.pptx
Blockchain Experiments 1-11.pptxBlockchain Experiments 1-11.pptx
Blockchain Experiments 1-11.pptxsaiproject
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - TalkMatthias Noback
 
Data Science in the Cloud @StitchFix
Data Science in the Cloud @StitchFixData Science in the Cloud @StitchFix
Data Science in the Cloud @StitchFixC4Media
 
Introduction to Blockchain Development
Introduction to Blockchain DevelopmentIntroduction to Blockchain Development
Introduction to Blockchain DevelopmentLightstreams
 
Deconstructing Monoliths with Domain Driven Design
Deconstructing Monoliths with Domain Driven DesignDeconstructing Monoliths with Domain Driven Design
Deconstructing Monoliths with Domain Driven DesignVMware Tanzu
 
Implementing Event Sourcing in .NET
Implementing Event Sourcing in .NETImplementing Event Sourcing in .NET
Implementing Event Sourcing in .NETAndrea Saltarello
 
Brownfield Domain Driven Design
Brownfield Domain Driven DesignBrownfield Domain Driven Design
Brownfield Domain Driven DesignNicolò 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 patterndwcarter74
 
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
 
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 SaltarelloITCamp
 
How to Build Your Own Blockchain
How to Build Your Own BlockchainHow to Build Your Own Blockchain
How to Build Your Own BlockchainLeonid Beder
 
Domain driven design: a gentle introduction
Domain driven design:  a gentle introductionDomain driven design:  a gentle introduction
Domain driven design: a gentle introductionAsher Sterkin
 
Building Reactive Real-time Data Pipeline
Building Reactive Real-time Data PipelineBuilding Reactive Real-time Data Pipeline
Building Reactive Real-time Data PipelineTrieu Nguyen
 
Predicting Space Weather with Docker
Predicting Space Weather with DockerPredicting Space Weather with Docker
Predicting Space Weather with DockerDocker, 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 CodeRoman Labunsky
 

Similar to Event Sourcing and CQRS Lessons from the Trenches with Blockchain (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
 
How to Build Your Own Blockchain
How to Build Your Own BlockchainHow to Build Your Own Blockchain
How to Build Your Own Blockchain
 
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
 

Recently uploaded

A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 

Recently uploaded (20)

A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 

Event Sourcing and CQRS Lessons from the Trenches with Blockchain

  • 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