Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A reading list that I'm collecting while building my Rust ES+CQRS framework: https://github.com/brendanzab/chronicle

Functional, Reactive, and Distributed Systems Bibliography

Books

Event Sourcing and CQRS

Diagram of CQRS+ES

Testing aggregates

Formal foundations

CQRS, DDD and Event Sourcing are informally defined design patterns. It would be nice to see a precise, theoretical foundation for these ideas. This could help find the signal in the noise and reduce confusion for newcomers. Interstingly, akka-persistence is an implementation of event sourcing that seems quite similar to state machine replication. Aggregates in this instance corespond to PersistantActors.

Aggregate design

Example Aggregates

Consistency, Distributed Transactions, and Sagas

CRDTs and Strong Eventual Consistency

Dedalus and Bloom

Split brains

Domain modelling using types and algebras!

Events and business rules map really nicely onto free monads and interpreters.

Designing a CQRS HTTP API

It can be a little hard to match up CQRS with traditional REST routes. There are a number of approaches I have seen mentioned, ranging from embracing RPC-style payloads to trying to translate CRUDful REST calls to commands.

Migrations and Schema Evolution

Table Schemas for Event Store Implementations

Alternatives

Datomic is a very interesting database! It splits the read side from the write side, and uses an append-only log for storing data. Unlike DDD-style event sourcing though, events don't correspond to domain events. Rather they are factual assertions that can be mapped to the more traditional 'CRUD' operations:

CRUD Datomic
Create Assert
Read Read
Update Accumulate
Delete Retract

The nice thing about this is that it allows one to hook into a more powerful and flexible query language than SQL, Datalog, that allows you to do historical querying. There have been questions raised about Datomic's scalability though (citation needed), and the database is tightly coupled to Clojure.

Contrarian Views

Some reality checks:

Implementations in various languages

  • aggregate: a collection of entities that cluster around a single root entity, referred to as the aggregate root.
  • aggregate root: the entity whose uuid corresponds to the uuid that identifies the entire aggregate
  • command: a message corresponding to a request to change the state of an aggregate.
  • entity: some data with an associated uuid.
  • event: a message that records an aggregate's state transition.
  • event log: an append-only record of all the events applied to the domain model.
  • read model: read-optimized caches that are subscribed to updates on the write model. Multiple read models can subscribe to a single read model.
  • uuid: a universally unique identifier.
  • write model: the source of truth of the state of a domain. This is often an event log.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment