functional cqrs - jetbrains@ramtop cqrs: when and why very good for complex mutable state separation...
TRANSCRIPT
@Ramtop
Functional CQRSFunctional CQRS
The double engine badass
@Ramtop
Have you ever
considered Event Sourcing
architecture?
@Ramtop
CQRS: When and Why
Very Good for✔ Complex mutable state✔ Separation of logic✔ Auditing required✔ Orders, Trades, Editors
@Ramtop
CQRS: When and Why
Very Good for✔ Complex mutable state✔ Separation of logic✔ Auditing required✔ Orders, Trades, Editors
Not good for✗ Read only aggregations (e.g. Reports)✗ Stateless calculations (e.g. risk)✗ Very High performance (e.g. exchange)✗ Trivial CRUD (e.g. TODO lists)
@Ramtop
Implementation Gradient
Command Pattern
Event Source
CQRS Monolith
CQRS Microservices
@Ramtop
Command pattern
✔ Allow replay to recreate State✔ Separation of logic from infrastructure✗ No automatic persistence✗ Limited Scalability
@Ramtop
Event Source
✔ Allow replay✔ Separation of logic✔ Automatic persistence✗ Limited Scalability
@Ramtop
Separation of Query Model
✔ Allow replay✔ Separation of logic✔ Automatic persistence✔ High Scalability✗ Complexity
@Ramtop
Split to Microservices
@Ramtop
Domain Driven Design
@Ramtop
Domain Driven Design
DDD is a creative collaboration between technical and domain experts.Domain language must be reflected in the code.
Code must let the business intention show up
@Ramtop
Immutability
Purity
Higher order functions
No exceptions
Transformations which preserse properties
Functional Programming
@Ramtop
DDD + Event Sourcing + Functional Style
There is no silver bullet but...
@Ramtop
@Ramtop
Protagonists
@Ramtop
What is a ADT?
Represent entities that can change state in an immutable world.
An algebraic data type is a kind of composite type, i.e. a type formed by combining other types. Wikipedia
@Ramtop
What is a Fold?
Specialized type of recursionIn functional programming, fold refers to a family of higher-
order functions that through use of a given combining operation, recombine the results of recursively processing its constituent
parts, building up a return value. Wikipedia
@Ramtop
Commands
A Command is a request for changing the internal state of the system
A Command can “fail” if is not congruent with the current state of the System
Each Command is executed in an atomic context
@Ramtop
Events
Events are the “atoms” of System state change
Nothing can change without an event, every event can change only one transactional aggregateState + Event => State
@Ramtop
Values and Entities
They represent the state of the domain
Values have no identity, Entities are distinct
They are all immutables
To keep state changes we have Algebraic Data Types
@Ramtop
Transactional Aggregates
An aggregate is an aggregation of Entities
They are composed by Entities and Values
It has all the information for a transaction unit
Aggregates is what Events fold to
@Ramtop
Queries
A query ask for a snapshot of the state
Queries typically need different data and denormalization from domain model. So we separate the models in CQRS.
Queries are only eventually consistent with the domain
@Ramtop
Actors
More powerful and easy to use concurrency model than Threads/Locks
They communicate asynchronously and potentially remotely
Useful for Bounded Contexts and ServicesRemote Actors works like Microservices
@Ramtop
Event Store
Store tuples (timestamp, type, uuid, event, version)
Query by index fast
Dynamic query
In memory implementation can be enough
@Ramtopgithub.com/uberto/anticapizzeria
@Ramtop
Antica Pizzeria
● Real application is about finance products booking but a pizzeria has a surprising similar domain
● We want to do implement the backend for a ChatBot that will assist booking and enquires about orders.
@Ramtop
Events Tree
@Ramtop
Commands
@Ramtop
Events
@Ramtop
Queries
@Ramtop
Queries listen to Events(to keep up with the changes)
@Ramtop
Let's fold Events(to create Entities)
@Ramtop
Entities as EventComposable
@Ramtop
Commands emit Events
@Ramtop
Logic is called by Commands
@Ramtop
Actors(where we can put all this stuff)
@Ramtop
Application
@Ramtop
Tests can process C&Q
@Ramtop
Add a new State to represent Dispatchwhen a pizza left theshop.Keep track of delivery person.
@Ramtop
Live Code
@Ramtop
Will you consider Event Sourcing in
the future?
@Ramtop
QAUberto Barbini
@Ramtop
github.com/uberto/anticapizzeria
@Ramtop