EventStore Design Patterns

We’re new to EventStore and are about to jump into design work. EventStore’s approach to Projections offer opportunities to write killer solutions, but look to also provide opportunities to get into a trouble as well. I was wondering if people could share some tried and true design patterns.

As a starter, what’s the best pattern for providing a projection on a category to refresh a service with folded data from each of its constituent streams?

  • Naming conventions? You’ve already got $ce-streamname, so what’s a good ‘go to’ choice?

  • Best to keep this projection live, or run it each time a server starts up? Any rule of thumb?

Joining Patterns for delivering results for master-detail data?

Process Manager patterns?

We’d appreciate any pointers to existing examples of patterns, or anything folks are willing to share.

Thanks!

Hi Leopold.

I have built a DDD stack based on event sourcing and CQRS.

It uses EventStore as an aggregate repository, and projections to write to a read model (RavenDb, Mongo, any RDBMS etc.)

It extensively uses BDD and TDD. ServiceStack is used for external access (web api), and NServiceBus on top of RabbitMq is used for intra-domain communication and saga orchestration (process management).

It is docker and CI/CD friendly. I plan to publish it soon, along with a blog where I will go through details. For now, there is a solution template that kicks it off with a single aggregate and projection.

Also, if you are new to DDD read Domain Driven Design by Eric Evans, Implementing Domain Driven Design by Vaughn Vernon, and Clean Code by Robert Martin.

When it comes to projections, it is best to keep it simple. In most cases $ce-aggregateName is enough. You can combine events for more advanced scenarios using custom projections where you hand-pick events you need.

Use catch-up subscriptions to handle events for reporting or any other purpose. Also, you will need to keep track of checkpoints used in your denormalizers/handlers.

Run application (write model) and read model as services/daemons.

This solution maps nicely to docker stack that is easily managed as a whole.

This approach should enable you to write fast and flexible apps. You will need need to know how to handle complexity though. It all comes down to proper domain modelling.

Hope this helps.

Best regards

Hi
Zvjezdan,

I’d be very interested in your solution.

I wonder how soon this will be available?

I’m also keen to contribute.

Thanks,

Sean.

On Behalf Of Zvjezdan Tomicevic

Hi Sean.
Hopefully in 3-4 weeks.

I’ll let you know.

Best regards.

Re projection. Simplest.

This stuff should all be simple.

I’ve never needed a framework - id argue MVC more complex with all its magic binding.

On startup

Read last seen event position

Subscribe to projection from this point

On event

Read last event seen position

If seen previously -> ignore

else -> read current readmodel state + push update data somewhere (dB, socket …)

Update last event seen version

If you want to fan out projections it’s a bit more complex. That’s competing consumers, the above is simplest (I use it most of the time - but then I’m not at the crazy scale some people are at. I can wait and process faster than incoming commands so I know I can catch up). A simple way for fan out is to partition on something (store last event seen against that worker) and then fan out.

Stream name is usually aggregate-id

And so category events are often at agg root level. Model event streams and projections and walk them through. That will point to boundaries. I have used DDD terms here but most of this fall’s out naturally from modelling I find.

Re live, projections for readmodels can cover many many streams and many events. They can take a while to rebuild and have memory footprint if you don’t use persistence and snapshot.

Also the read side is usually optimised for read speed rather than consistency.

But if you really needed a consistent read model then you could replay whole stream each time and wait. But that should be slower than reading a pre unfolded event stream. But everytime I think I want this I find it is because of a non reactive UI element. Something should give and a consistent readmodel is generally not the answer.

So keep projection live. Master detail usually is in same aggregate or else you are crossing contexts in which case a domain event (some events are internal to an aggregate and some are published domain events) should exist to trigger something in another context (eg detail) which you can project from. Master detail might involve 2 or more read models if it crosses contexts.

Process managers seem to have many many options depending on needs all with trade offs in coupling and error handling. Every time I write one I’m still trying new things so dare not suggest anything.

I do as above hopefully someone can provide insight if it’s lacking!

John