3

I have a system that uses CQRS with the Queries written using Dapper. It's worked out well, except that there has been a proliferation of query classes that do almost the same thing. The downside of this is that additional queries mean additional maintenance overhead (especially because of the SQL strings) and other problems associated with having lots of small classes, but the upside is that the classes conform to the Single Responsibility Principle and are somewhat easier to reason about.

If I was using stored procs, I'd probably just create a few bigger, general purpose queries (in order to mimimize the overhead of maintaining the SQL) but the opposite seems to be the case in this implementation.

What's the best approach in terms of query size? Should there be a query per viewmodel, or should the queries be decomposed?

NMrt
  • 479
  • 3
  • 9
  • The use of Dapper is not relevant here. You use the granularity of queries that you decide is a fair tradeoff between reusability and separation of concerns. – Robert Harvey Nov 01 '16 at 02:12
  • Based on your edit, it sounds like you've hamstrung yourself with a literal reading of CQRS. If you bend the CQRS rules a bit, and put in your WHERE clause, and shape the data using parameters, will that solve your problem? – Robert Harvey Nov 01 '16 at 02:32
  • @RobertHarvey Sure, but I'm part of a team, and the consensus that emerged was atomized queries, and I was wondering about the validity of the other approach, and how it's worked out for others and the downsides experienced with chunkier queries. – NMrt Nov 01 '16 at 02:36
  • This article seems to adequately describe the tradeoffs: http://martinfowler.com/bliki/CQRS.html – Robert Harvey Nov 01 '16 at 03:16
  • @RobertHarvey Thanks, that was a good read. CQRS is actually working out quite well for the system. My question is about a specific implementation detail on the Query side of a CQRS application. – NMrt Nov 01 '16 at 04:38
  • So you think you can add the parameters, make your SQL a bit more complex, and simplify things overall without breaking CQRS? Problem solved, I'd say. – Robert Harvey Nov 01 '16 at 04:42
  • Indeed, I would think so, but I'd like to know what the gotchas are, and if this is frowned upon generally. I know the downside of fragmented queries, but I have only got a vague idea of the downside of the alternative, but I'd like input from people who dealt with this, and made the other decision to go the other way. – NMrt Nov 01 '16 at 04:46
  • There isn't enough information in your question to make that determination. – Robert Harvey Nov 01 '16 at 04:47
  • do you mean having dynamic sql (after the where clause) vs static with inserted parameters? ie where id=#id – Ewan Nov 01 '16 at 08:50

1 Answers1

1

It's worked out well, except that there has been a proliferation of query classes that do almost the same thing.

Based on my understanding, that sounds suspicious. Not wrong necessarily, but it would give me an itch to peruse the architecture decision records to understand whether my predecessors and colleagues were following their understanding of dogma or comparing trade offs against a specific set of priorities that set them down that path.

If I was using stored procs, I'd probably just create a few bigger, general purpose queries (in order to mimimize the overhead of maintaining the SQL)

That seems like a pretty reasonable approach to me too. "You aren't going to need it", and all that.

What's the best approach in terms of query size? Should there be a query per viewmodel, or should the queries be decomposed?

My understanding is that the read model should be pretty thin; we're supporting an API, and if we have done it right that ought to be stable. The actual mechanics of reading the data out of the persistence store ought to be prioritizing simplicity or (minimum) latency, depending on the value to the business.

In particular, when you identify a specific query in the API that needs special care (it needs to meet an especially tight SLA), it ought to be trivial to refactor the implementation into its own code path (which you can then start optimizing).

My suggestion would be to review CQRS - but different, by Udi Dahan (talk) (slides). In this case, I'm thinking of his point that if making a change requires repeating yourself in layer after layer, then something has gone sideways.

VoiceOfUnreason
  • 32,131
  • 2
  • 42
  • 79