CQRS: how granular should the queries be?

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?

9

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.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *