A thread about what we have learned after ~1y of #EventSourcing.
Context:
- Domains: Billing, Accounting, Cashflow.
- Volume: 750k events / day
- Services count: 10
- Private cloud/infra
- Stack: #fsharp / postgres / rabbitmq
Caution:
Very opinionated, we're learning every day.
Without modeling, never create a new stream or add a new event. Your self-confidence could be your enemy.
Event names and event models must be double checked with the business and the team.
Events should always be business events.
Avoid using them or their fields as a logger (You have elastic for that).
"AlreadyReceived" for example, should not be an event but maybe a command error.
If there are large event models, it's best to persist them in a cloud storage and just use the reference on events.
Code smell: If multiple events of the same stream have the same model.
It means bad modeling and so bad maintainability and performance.
Every action is not a command.
It's normal that a command could generate multiple events.
Commands that are never triggered directly from outside, must be removed.
Cost of sync projections + transaction is much higher than async projections !
We can even say that they are not really production ready.
Event Sourcing is one of the best strategies to progressively migrate a legacy and supporting parallel runs (multiple projections).
Never let projections become wild monsters.
Keep them simple and above all idempotent.
Resilient services and infrastructure with Transient fault handling are so much harder than Event Sourcing itself.
But this is true for every thing.
Reference data should not be duplicated in events data but only their ids.
This is a basic and global architecture rule which here allows less coupling and also less event versioning.
Because of ES/Onion arch, first time I see a domain (pure) larger than other layers and other layers more generic.
This also allows us to focus on infrastructure optimizations without changing a single line of business logic.
Always protect and isolate domain events.
Having an ACL (a simple mapping + logic) at input and also a mapping at output (app events), has helped us a lot, real life saver.
To have less coupling and so different bounded context life-cycle.
• • •
Missing some Tweet in this thread? You can try to
force a refresh