Command Query Responsibility Segregation (CQRS) and Event Sourcing
Today I read an Interesting article about CQRS and Event Sourcing on heise developer (in German). The authors describe a system architecture that employs two concepts: Command Query Responsibility Segregation (CQRS) and Event Sourcing. The two approaches complement each other quite well, but they are not without problems.
CQRS is about using different interfaces and data models for commands (that change the system’s state) and queries (that do not change the system’s state). This is in contrast to more or less CRUD-based approaches, where you find operations such as “void saveUser(User user)” and “User getUser(id)”. Note that a “User” object is used in both a command operation and a query operation. They are probably part of the same interface, too (which is a potential violation of the Single Responsibility Principle and the Interface and Segregation Principle). Event Sourcing means to capture and persist all events changing the system’s state. This way, your domain model’s current state itself does not need to be persisted. It can be reconstructed by “replaying” all events in their original order. The appeal of this approach is that all state-changing interactions with the system are automatically logged. If you use a dedicated event store, you neither need a relational database nor an OR Mapper. But, without a database, you will have to code complex analytical queries against your query domain model. If your domain model’s instances don’t fit in your main memory, you might run into trouble here. But memory is cheap these days.
Another problem I see in using an Event Store is data migration. Imagine you want to replace an old application you didn’t develop, but reuse its data. If the software vendor used a relational database with a decent design, your data would be in a “standard” format. You can inspect, extract, and transform it using a variety of tools. It is not bound to the application (if the vendor could resist using triggers, stored procedures, etc.). If the vendor used an Event Store, you could not directly reuse its data. This is because it is kind of “delta encoded”. You need the application to do the decoding, i.e. the logic that constructs your domain model instances from a series of events. You would have to develop a snapshot exporter. But while you usually have access to your database, you do not necessarily have access to the application’s source code. So keep in mind: Event Sourcing tends to tie the data storage layer and the data access layer together quite strongly! Just by looking at the data in the event store, you will have a hard time determining the current state of your business data.
Picture: Some cables behind my TV set