0

Is having a separate read only and write only data store a core part of CQRS, or does it still make sense in some scenarios to do CQRS with a single data store?

Asking because a coworker is using CQRS terminology in a project. Whether or not he's actually using the pattern I can't say because I'm not familiar enough with it to know, but my first impression is that it's just a regular REST service where he is using separate objects for saving data with POST operations than the ones used to retrieve data with GET operations.

My first impression on CQRS is that the shape of the data at rest is different for reading and writing, whereas here the same database is used for both.

Am I perhaps missing something about the purpose of CQRS and its usefulness in a scenario like this?

3 Answers 3

3

CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).

When most people talk about CQRS they are really speaking about applying the CQRS pattern to the object that represents the service boundary of the application. -- Greg Young, 2010

My interpretation of this early definition is: no, separate data storage for reads and writes is not a constraint.

The CQRS pattern, to some extent, enables a number of interesting choices, which can of course include designing your data storage so that reads and writes can be tuned differently. But that tuning is a different thing from the CQRS pattern itself.

1

I'm afraid I have to disagree with other answers. CQRS is an architectural pattern that alters the data flows and needs to integrate data between the write store and read store via other practices and patterns such as EDA (event-driven architecture) concepts and patterns. Making separate ways to handle the commands and queries is what CQS is all about. Writing code with CQS style makes it easier to make CQRS architecture decisions. When you write your code with CQS in mind, the road to achieving CQRS is halfway gone.

Is it good to use CQS? I say, Yes. When you separate commands and queries:

  • processes are clearer
  • separation of concerns has complied
  • you can focus on the read-model more efficiently for performance
  • you can focus on write-model for implementing domain logic to be more accurate and authentic
  • it helps you to make decisions about choosing CQRS in the future
0

This is getting close to being a philosophical discussion.

If a tree falls in the forest and no one hear it, did it make a sound?
If a codebase has split commands and queries but both sides refer to the same data store, is it CQRS?

Abstractly, I'm going to say yes to both questions. A sound is defined by a wave, not by its perception. CQRS is defined by having separate commands and queries (hence the name); having separate data stores is usually the ultimate goal and justification for doing CQRS but it's not inherently part of the definition.

In a past project I've worked on, we weren't sure what the performance was going to be like, as we had no concrete numbers on eventual adoption rate. Therefore, we decided to pre-emptively implement CQRS in the codebase, but to only use one database.

The benefit here is that we could save on DB server running costs for as long as there was no performance issue; and when such an issue presented we would not need to change the codebase, only one of the two connectionstrings in the config (which up until then had contained the same value.

From the POV of the developer, they are building a CQRS-oriented codebase. Whether or not the physical data stores are separate is irrelevant for the developer, as they have to write their code to account for them being separated anyway. Therefore, there is no meaningful benefit from defining CQRS based on the actual data storage devices.

he is using separate objects for saving data with POST operations than the ones used to retrieve data with GET operations

That is not CQRS though. Whether or not your reuse your API model across several endpoints has no bearing on whether you're doing CQRS.

Separating your models is one of those things that sometimes occurs when you're also doing CQRS, but in and of itself it does not fall under the umbrella of "doing CQRS".

My first impression on CQRS is that the shape of the data at rest is different for reading and writing

REST promotes reuse of the same API model across its endpoints. That's not a hard and fast rule (e.g. in cases where some fields cannot be updated after initial creation, you'd have a different update model); but in either case it has no bearing on whether you're doing CQRS.

What matters for CQRS is that a particular endpoint only reads or writes, it does not do both. For example, you should not have an endpoint which updates a value and then returns the updated version of the object.
Note that I'm excluding return values which act as confirmations that the write action succeeded. That's perfectly fine. I'm focusing on return values which contain the same data object that your were also writing to.

Just for completeness' sake, the CQRS split needs to persist all the way down to the persistence storage, otherwise there's no point.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.