ddd, cqrs & es lessons learned (gitte vermeiren)
TRANSCRIPT
ES, CQRS & DDD: Lessons Learned (and walls bumped into)
Gitte Vermeiren | @GitteTitter
One does not simply
Use ES, CQRS & DDD
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Handler
Data
Thin Data Layer
Query DTO
Event BusEvents
Person
Dossier
Payment
TechnicalInvestigation
DocumentGroup
Task
TaskClosedEvent
TaskPerformedEvent
DocumentRenamedEvent
TaskCreatedEvent
DocumentJudgedEvent
DocumentAddedToDocumentGroupEvent
DocumentMovedEvent
DossierApprovedForPaymentEvent
DocumentPrintedEvent
https://github.com/MarkNijhof/Fohjin
Problem 1
“Every ‘dossier’, ‘scan’, ‘decision’, ... Should have a unique incremental number”
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Handler
Data
Thin Data Layer
Query DTO
Event BusEvents
Use an autoincrement
column?
Use a ‘DossierNumberGenerator’
DossierNumberGenerator
_highestNumber = 01. GenerateNext
2. DossierNumberGeneratedEvent
3. onDossierNumberGenerated_highestNumber ++;
DossierNumberGenerator
_highestNumber = 0
onDossierNumberGenerated_highestNumber ++;
DossierNumberGeneratedEvent
DossierNumberGeneratedEvent
DossierNumberGeneratedEvent
Replay
Repository.GetById<DossierNumberGenerator>(id);
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Handler
Data
Thin Data Layer
Query DTO
Event BusEvents
Use a domain service
Problem 2
DomainEvent
Id
AggregateId
Version
Raised
repo.GetById<Aggregate>(aggregateId);
Get/Store events based on type, not on
eventproviderId?
Migrate those events
WIP
AnotherNewRefactoredAggregate
ANewRefactoredAggregate
anAggregate
SomeEvent
SomeOtherEvent
AndSomeMoreEvent
Migration Process
SomeEvent
SomeOtherEvent
AndSomeMoreEvent
AndAFunkyEvent
https://github.com/vermegi/Eventstream.Migratorhttps://github.com/NEventStore/NEventStore.Migrations
Event StoreEvent Store
Read the entire event stream Save the entire event stream
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Handler
Data
Thin Data Layer
Query DTO
Event BusEvents
Replay needed
Event Versioning with an EventUpdater
AnAggregate
_somePrivateStuff = 0
onSomeEvent:_somePriveStuff = somevalue;
SomeEvent
AnotherEvent
AndAnotherEvent
Replay
Repository.GetById<AnAggregate>(aggregateId);
SomeEvent
AnotherEvent
AndAnotherEvent
Update
Repository.GetById<AnAggregate>(aggregateId);
SomeUpdatedEvent
AnotherEvent
AndAnotherEvent
AndAnotherEvent
Problem 3
AnAggregateSnapshot
Repository.GetById<AnAggregate>(aggregateId);
_version = 666
SomeEventVersion = 667
AnotherEventVersion = 668
AndAnotherEventVersion = 669
AnAggregate
_somePrivateStuff = 0
onSomeEvent:_somePriveStuff = somevalue;
Replay
Problem 4
Hard to use in debugging
Hard to do data updates
Hard to query
Problem 5
AnAggregate
_somePrivateValue = 0DoSomething
onSomethingHappened_somePrivateValue = something;
DoSomething
SomethingHappenedEvent
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Handler
Data
Thin Data Layer
Query DTO
Event BusEvents
Hard to do data updates
Reuse the same logic
Do it functional
Problem 6
And for the good news?
Some final thoughts ...
VISUG Partners