Inspiration
Our journey towards elevation of our event-sourcing code abstraction level started with an inheritance-based model, that we described in this article. We introduced EntityCommand
and EntityEvent
traits, which allowed us in turn to define someCommandProcessor
and EventApplier
constructs with generic implementations and mappings for Akka. This was already a good step in the right direction as it allowed us to host command handling and event handling logic in the domain, free from any Pekko/Akka dependencies.
Implicit commands & replies
However, with this approach, commands and replies are still an integral part of the domain model. And if you think about it, such models and associated mappings to/from values do not add any value to domain expression, rather the contrary. Domain code is more compact if we can use straight algebras and values, without concern for the underlying necessary reification to cross node boundaries in the cluster. It was also always an open question for us how to best integrate event sourcing within functional codebases. Since event-sourcing looks a lot like a reader-writer monad, we felt there was some potential there.
Aecor
At this point, we ran into the outstanding work done by Denis Mikhaylov & contributors on Aecor as well as the excellent blog series by Vladimir Pavkin. This was an eye-opener, and we highly recommend the read!
However, we could not use the library directly for a number of reasons, chiefly because we are attached to keeping the layer above Pekko/Akka as lightweight as possible and we want to keep control on serialization aspects. There also are other more subtle differences: for instance we consider command rejections (and more generally, “business errors”) as first-order values, therefore opting for Either
for replies. In endless, we’ve also tried to stick close to DDD & Pekko/Akka nomenclature as much as possible.
Bridging the gap
By providing of typeclasses allowing for expressive description of entity behavior and embedding common event sourcing patterns into these abstractions, we hope to make it more approachable to enjoy side-effect free programming while still benefiting from the great power of Pekko/Akka.