Discussing about a CQRS implementation with my team we don’t agree on a point concerning the Query side.

On the Commad side we have actual command clases; a CommandDispatcher that schedules commands, defines a Unit of Work scope and dispatches commands to handlers; handlers that contain the business logic and do CRUD operations using repositories.

For the Query side the team is split on two:

  1. One part of the team says that a simple read service layer is enough, services that access directly the data source (no repositories) and can be called directly from callers (no query classes nor a query dispatcher).
  2. The other part of the team says that we should build the Query side symmetrically to the Command side, having query classes, a query dispatcher and fetch data from repositories.

We don’t need any synchronization nor scheduling system for queries (query dispatcher) and query handlers must be mostly classes that return data fetched from repositories. So we would add potentially unnecessary extra layers only for the sake of symmetry.

Any thought?

  • 2
    The whole point of CQRS is that your read model can be designed to be convenient for querying and that you're not tied to a model that is optimised for writes. That can be many different read channels, with many different structures, designs, technologies and even data stores depending on use case. The "read side" is not a single application with a single structure, it's whatever you need to build to get your data how and where you need it. It sounds a like you're trying to "make an application CQRS" and not realising that it is a higher-level architectural design concept. – Ant P Dec 4 at 13:14
up vote 1 down vote accepted

Disclaimer It may be personal opinion.

There exists another design principle: KISS -Keep It Simple...

Simple Repository can make some advantage as can simplify the code of your services, but going deeper can not be certainly necessary.

You have to think out what are your business values of making over-engineered query engine.

  • Do you expect that you will need to pass queries between subsystems? If so then some dispatcher can be helpful (I would name it router then anyway).

  • Do you expect that you will need to add new query parameters frequently? If so, query classes will be certainly needed.

One property to notice about queries is that they don't change the state of the domain data. It follows that you don't need all of your domain logic to ensure the integrity of the data -- that check was already done when you wrote it.

So there's not a lot of value in loading your data into a data model just to pull it back out again.

You may want some boundaries in place, to ensure that changes can be isolated and duplicated code can be re-used.

Symmetry is not a useful goal unless it somehow reduces your maintenance costs. Ceremony is worthless.

  • We do have this "segregation" so it is not possible to mutate data from the read side and reads can be specific to each need without depending on the write model structure. I also agree on the side that adding extra layers for sake of symmetry will reduce maintenance but it's hard to some developers to accept that querying and commanding the core domain is done using different paradigms. – polkduran Dec 6 at 10:12

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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