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:

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).

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.

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 PDec 4 at 13:14

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.
– polkduranDec 6 at 10:12