Category Archives: SOLID

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:

 

1? Or…2?

I promise I’ve got some code samples coming down the pipe, but I’ve found another article which really caught my attention and I couldn’t resist the urge to provide my commentary.

(just in case you weren’t crystal clear on my development philosophy)

Thoughts on Agile Database Development

First off, I’m madly in love with Marten + Postgres.  The whole idea of a hybrid relational/object store at first prompted me to sound the alarm about one package or database being guilty of “trying to do too much”.  After working with it (albeit, on personal projects), boy was I wrong.  It’s really the best of both worlds – the friction-less object storage aspect (reminiscent of RavenDB or MongoDB – by design), combined with enough control to satisfy the majority of DBA’s I’ve worked with, makes for a truly new experience in the ORM world, where we Microsoft goons have been spoon-fed entity framework for many years.  I swear I spend more time configuring EF6 then I do actually writing code that matters.

The comparison of Postgres to MSSQL Server is out of scope here, but suffice to say that if you’re willing to take a dependency (normally something I would absolutely never accept), you’ll be richly rewarded.  Not only is IDocumentSession tremendously optimized for a given query or command (see my posts on CQRS), but the surrounding tooling for doing real life deployment tasks is tremendously useful, especially considering this thing is FOSS.  Schema comparison through the Marten command line takes so much work out of having to manage which SQL changes happened when, assuming you don’t have an expensive enterprisey tool to handle that stuff for you.  Even if you do, chances are it’s not linked up with your POCO’s, which is where all the interesting action happens.

Which brings me up to the next point – software design philosophy.

Quoted from Jeremy’s post –

“The” Database vs. Application Persistence

There are two basic development paradigms to how we think about databases as part of a software system:

  1. The database is the system and any other code is just a conduit to get data back and forth from the database and  its consumers

  2. The database is merely the state persistence subsystem of the application

Wow.  Nailed it.  I feel that there’s so much talk about DDD, stored procedures, ORMs, business logic, performance, ACID persistence, and which-team-owns-what-code that we never even stopped to ask ourselves, “am I a ‘1’ or a ‘2’?  The answer to that question shapes the direction of every system you build, and all systems that your team builds.

Alot of conflict I see arise in Software Development in my company comes from this aspect of writing code for the simple purpose of putting data in the database.  This is fine until you run into a non-trivial set of business rules and external integration points.  In my experience, one of the highest killers of scalability is over-reliance on a monolithic transactional store.  Our obsession to save a few bits of hard disk space has led to a colossal convolution and violation of separation of concerns.  I’m not allowed to pull a customer’s purchase history because there are 12 joins involved and the performance is too slow?

When did that become acceptable?

Now, Marten is not the golden hammer to this problem, but rather the design philosophy of the team that created it is explicitly aligned to more domain oriented thinking, versus the philosophy of “all hail the mighty column”.

His point about an Application Database hits home too.  I lost count of the number of times our dev team broke the database in our dev environment.  Being able to stand up a local copy for isolated testing (or intentional breaking) is unbelievably useful for anyone that gives a crap about proving the durability of their system.  I’m going to give Jeremy some more free linkage related to the shared database antipattern.

I added a Marten project to my Bootstrapper GitHub project to help capture some of my initial work with Marten.  It’s really for basic copy-paste reference, or a fast import of generally used CRUD methods that you’d want to hot drop into a File > New Project experience.  I still need to commit my VS 2017 migrations to master…

As an aside,

If you’re spending more time in SQL schema design meetings than you are with the domain experts, you’re doing it wrong!

But again, that statement depends on whether you’re a 1 or a 2…

I’ll leave the discussion regarding the ‘Vietnam of computer science‘ for another day.  Happy coding, friends!