Reputation: 4331
I know that CQRS
can be implemented with or without event sourcing
, but does it work the other side? Does event sourcing
without CQRS
make sense? If so, how it should be implemented?
Upvotes: 15
Views: 3388
Reputation: 8273
Yes, event sourcing can be used without CQRS (as the existing answers have already pointed it out), but the need for implementing the separation of writes (of events, logs, etc.) from reads (from projections, views, etc.) seems to come naturally when reaching a certain level of complexity.
Came across the post The Log: What every software engineer should know about real-time data's unifying abstraction by accident, and even though it is about event-driven distributed systems, one can easily find the parallels between the concepts described in the text and CQRS + event sourcing. It's a long and dense article, but is well worth reading.
To quote the most relevant part under the section "The place of the log in system architecture":
Here is how this works. The system is divided into two logical pieces: the log and the serving layer. The log captures the state changes in sequential order. The serving nodes store whatever index is required to serve queries (for example a key-value store might have something like a btree or sstable, a search system would have an inverted index).
Only tangentially relevant, but after reading The Log article, I was immediately started reseraching on how to connect the dots between the concepts it describes and CQRS + event sourcing - and, consequently, why (almost) no one recommends Kafka as an event store. This answer is the best in my opinion, and the terminology introduced there feels underrated (i.e., "downstream event processing" and "application-controlled source of truth").
Upvotes: 0
Reputation: 113
CQRS is about separating the reads from the writes. Write operations need things like locking, guaranteed order, and always the latest state. In classical systems (relational databases) you would also give this guarantees to read operations, which comes with a huge performance impact and big issues when it comes to scalability. That's why in CQRS you give read operations a separate copy of the data which is optimized for fast reads, e.g. it is denormalized and put into more efficient, faster systems (e.g. a memory cache), I'd call this a "read view [on the system's data]".
CQRS works without ES, because you can create the optimized read view from a traditional data store (e.g. a relational database).
ES does work without CQRS, but only if the number of events is reasonably small. Because you are storing all the changes of the system in a database and every read has to use the same database and iterate over all events that it needs to fulfill the query. Eventually there will be too many events that need to be read in order to answer and the time it takes to answer will become too long.
Upvotes: 9
Reputation: 86
I've yet to see a situation where you use ES without CQRS because this would only be the case if you do not need any query/analyses capabilities across more than 1 entity. 99% of all cases this is a requirement ;)
You will definately need something like CQRS if you want to query over multiple entities as you will apply a different way of querying your data other than using event sourcing. (unless you want to replay all events every time you query..) How you go about implementing the CQRS part isn't set in stone though. It just describes reading and writing are 2 seperate concerns handled in different ways.
So in general: No, this does not make any sense.
Upvotes: 3
Reputation: 150654
Yes, it does.
Basically, the entire idea of event-sourcing is just to store the changes that led to the current state, instead of storing the current state. This way, with event-sourcing, you automatically have a history and can run time-series analysis on your data, and try to learn from the past.
Whether you use CQRS is a completely different story: CQRS is about separating the writing to your application from reading from it.
In the same way you can use CQRS without event-sourcing, you can use event-sourcing without CQRS. Both are independent of each other, they just accidentally fit each other very well.
Upvotes: 15
Reputation: 57259
Does event sourcing without CQRS make sense?
Yes, in the sense that CQRS and Event Sourcing are orthogonal concerns.
It's what it says on the tin - you have one model that manages a history, both applying updates to that history in response to commands and constructing from that history the responses to queries.
class BankAccount {
final History<Transactions> transactions;
void deposit(Money money) {...}
Money computeInterestAccruedSince(Date lastReview) { ... }
}
Upvotes: 2