Query Results

CQRS – Command – Query Responsibility Segregation

If this is brand new to you, I would encourage reading Dino Esposito’s exposition of it in MSDN magazine – here.  A little history goes a long way!

Just wanted to provide a little commentary today on my take on query results.  When I opt into CQRS classes in my API’s, the only way I’ve done my queryresult statuses (thus far) is to have an enumeration representing the possible states of the query result.  Some projects might choose to have a unique status per command (using some fancy generic magic and such), but I never quite found that appealing.  As an example, here’s the typical bare minimum I would need for a controller (or any other interested class) to diagnose a queryresult:

If a query is particularly long lived, or was forced to cancel or somehow return as incomplete from a database, NotYetProcessed is our first line of defense.  This is also super handy for new handlers, as I’ll typically forget to set this on my first run through new handler code, and inevitably there is a switch statement on an extension method that catches it and immediately alerts me to the mistake.  I rather enjoy the fail fast behavior of having a default of NotYetProcessed .

More importantly, being able to write extension methods against this enum allows me massive reuse all across related projects.  Repo’s can map their states to it; controllers can return status codes based on it.  It’s fully standalone, matches the spirit of query objects perfectly, and is also fully encapsulated.

A comment on the NoResultData status.  I keep this because checking null or empty isn’t particularly elegant, and in some cases it’s a performance benefit to bypass serialization altogether if we know ahead of time that there’s no concrete result (even though a given routine may prefer Enumerable<T>()).

I’ll be committing some sample usage to my ApiKickstart repo.  Have a look!

Today’s music – threw on some YouTube randomness and ended up here:


Leave a Reply

Your email address will not be published. Required fields are marked *