Tech News
← Back to articles

Rethinking CQRS: An Interview on OpenCQRS

read original related products more articles

Rethinking CQRS: An Interview on OpenCQRS¶

Golo: Frank, you are one of the managing directors at Digital Frontiers and also one of the architects and main developers of OpenCQRS. Over the past months we've seen a lot of interest in the framework, especially now with version 1.0 out. Some of our customers have even been building production systems with the release candidate for quite a while already, which shows how stable and usable it has been early on. Before we dive into details, let's start at the very beginning: can you tell us a bit about how OpenCQRS came to life? What triggered the idea and what gap were you trying to fill?

Frank: To be honest, OpenCQRS started out as an experiment or prototype back in 2024. When the two of us first met each other to talk about EventSourcingDB, I immediately recognized that it contained a lot of hidden gems, such as hierarchical event streams. So, imagining a suitable CQRS framework on top of the EventSourcingDB did not feel like building yet another framework. Instead we were eager to expose those gems to Java developers, who might not even know yet, what they lacked so far.

A colleague then started out by implementing a first prototype on a train ride to Hamburg. The result, though in a very early draft state, convinced us that we could come up with a very clear design for CQRS applications. We especially focused on getting rid of some of the annoying relics of typical CQRS frameworks as well.

Moving Beyond Aggregates¶

Golo: I know that quite early on you decided to move away from the traditional aggregate pattern, which is a pretty bold step since aggregates have been central to Domain-Driven Design (DDD) for years. Instead, you speak about No Aggregate. Can you explain how this idea evolved and why you deliberately stepped away from the classic approach?

Frank: Well, this is definitely the number one relic that we abolished: I've never felt very comfortable with the term "aggregate", as the term does not express clearly, which problem it actually addresses, at all. In the end, events are the predominant aspect of CQRS/ES style applications. So, in order to decide whether a command is acceptable or not, you need to aggregate the relevant events in order to make that decision. The aggregate therefore determines your consistency boundary, that is, which events need to be sourced to make this decision and – from the perspective of the underlying event store – to assure that new events published don't violate these consistency constraints.

So from a developer's perspective it felt wrong to impose the term "aggregate" on them, when a simple, immutable write model class – for instance a Java record – is all you need. In the end, the developer has to decide, which events are necessary for a specific command to be handled properly. Put differently, one might choose completely different write models for different commands all related to the same aggregate. This flexibility is what we considered more valuable than enforcing the term "aggregate" within the code.

No Aggregate vs. Kill Aggregate¶

Golo: That reminds me a lot of Sara Pellegrini's talk "Kill Aggregate!", but you've pointed out several times that your goal isn't to "kill" anything – you deliberately call it No Aggregate. Could you explain the difference and what mindset shift developers should have when moving to your approach?

... continue reading