No, you’re not dreaming

Yep, I’ve decided to start writing, just like that, out of the blue! And two tweets are to “blame” for this.

Vicenç asked this question on Twitter:

@iceoverflow @msanjuan @luisruizpavon when you use MediatR and add validations to it, do you skip validations in the controller? Do you duplicate them? Do you validate different things? And in the entities? Do you add validations in the constructor again?

— Vicenç Garcia (@vgaltes) February 26, 2020

And, when my answer was turning into a long string of tweets, I remembered this other one:

Another day when Modesto justifies Twitter threads. Shall we chip in for a blog? https://t.co/zpGHgn4EGi

— Jorge J ‘Jorhell’ (@flipper83) February 16, 2020

Leaving aside the fact that Jorge is a professional troll, sometimes he’s right. And I think this is one of those cases where I’ll feel more comfortable putting my answer in writing, in a medium that lets me go off on a bit more of a tangent.

OK, but what about the validations?

First of all, the obligatory answer: IT DEPENDS

And it depends above all on how you’re approaching your application’s architecture, what you need, and how far you want to “complicate” your life.

So, to turn that “it depends” into something a bit more concrete, I’m going to try to explain it based on a reference architecture model that’s all the rage right now, and then everyone can extrapolate to their own scenario and draw their own conclusions.

An example with Clean Architecture

When we talk about Clean Architecture, the usual thing is to show this diagram or one of its variants: Typical Clean Architecture diagram

Clean Architecture draws boundaries between responsibilities that set expectations about what should happen in each slice of the diagram. For example:

  • When we’re talking about business, it’s assumed that we’re in a safe environment where there’s no room for authentication or authorization concerns.
  • No business object should be constructible while breaking the business invariants.
  • The application layer knows nothing about the delivery mechanism. A use case could just as well be invoked from a controller or from a command-line application.
  • Authentication will generally be the responsibility of the web framework, but authorization will be the responsibility of the use case.

And we could keep listing characteristics of this kind of architectural pattern, but that’s not the goal of this post; I just wanted to give a bit of context.

If we’re also applying DDD, we’ll have to add more rules, constraints and heuristics to the list, but the important thing is that we’re aware of what they are, so we can assess in each case whether we’re following them. We could even verify them automatically with architecture tests.

Mind you, for this purpose I don’t care whether it’s Clean Architecture, Ports&Adapters, Onion Architecture or whatever. I also don’t much care which combination of language and framework we’re using. In the end, what matters is that we’re essentially talking about approaches that separate the business from the delivery mechanisms and from the use cases.

And what’s this Mediatr thing?

Mediatr is an implementation of the mediator pattern for .Net that lets us run our use cases while taking advantage of the .Net dependency container, and also gives us the option of adding behaviors before and after the use case itself runs.

If we take the previous diagram and Vicenç’s question as a reference, and stay at a fairly high level of abstraction, we could assume that a typical call to our API would look something like this:

API call -> Asp.Net -> Controller -> Mediatr -> Use case -> Entity

Sometimes it can feel a bit odd, because what we’re doing is using a pipeline inside another pipeline (Asp.Net’s own). But keep in mind that we can perfectly well use mediator in other contexts, like as part of a message processor for a queue. That would look like this:

Queue Subscriptor -> Message processor -> Mediatr -> Use case -> Entity

Personally, I find it very useful to imagine two different scenarios from the delivery mechanism’s point of view; it helps me assess whether I’m putting things where they belong.

You sure like to play hard to get… but where do I put the validations?

After all this drag trying to provide a bit of context, the answer is still IT DEPENDS. Let’s go back to the questions, assuming we’re using validations with Mediatr.

Do we skip validations in the controller?

In the controller I put the validations related to the delivery mechanism. For example, authentication is a kind of validation, and that check should already be done by the time things reach Mediatr.

Although that’s one example, we’d normally put few validations in the controller, since most validations tend to happen at the application level, that is, in the use cases.

It’s a different story if you tell me you’re using the framework of the day, which makes it really easy to validate certain data as it arrives at the controller, and that you’d like to put some validations there. Well, then we get into the usual trade-offs. The important thing is always to keep in mind that your use case won’t necessarily always be called through a controller; remember the example I gave above with a message queue.

Personally, that last thing is something I’d rather not do. I’m sure that, if you’re going to buy magic, you can buy it for the right layer of your architecture, and at least you’re respecting the boundaries.

Do we duplicate them?

No, unless it’s for UX reasons and very much as an exception (see the explanation below)

Do we validate different things?

That’s the key. Normally we validate different things, and that’s why we put them in one place or another.

Following the previous example, authorization is something we’ll normally do in the application layer. If it’s relevant, our use case will receive the information about the authenticated user, and there we can do whatever security checks we see fit.

Another typical example comes up when we need validations that require interacting with repositories or similar. These validations clearly belong in the application layer, so they’d fall under the validations we do within Mediatr.

What do we do in the entities? Do we add them again?

In the end we have to apply the same heuristics again. In the entities we should only put the validations that belong to the business.

For example, if the business doesn’t allow invoices to be created without invoice lines, this validation should go in the corresponding entity, and we shouldn’t repeat it in controllers or the application layer.

Once again, UX may come along and destroy our perfect dreams.

And what about UX?

We shouldn’t lose sight of the fact that we build software to be used by people. Our users couldn’t care less whether we’re using a textbook hexagonal architecture or have controllers the size of a Russian bomber.

And that’s why there are times when we may have to throw everything described above in the trash just to provide a better user experience.

Even so, when we duplicate validations across different layers of our application, we’re entering the wonderful world of connascence of algorithm. Anyone who’s been doing this for a while has faced the problems that come with it and, honestly, it tends to be worse than a toothache.

An option that respects both UX and architecture

If we see that our application keeps forcing us to make a lot of concessions on validations for UX reasons, we should ask ourselves whether the validations are use cases in their own right.

Depending on our design, this wouldn’t be very hard to achieve, and it would let us respect the UX while also respecting our architectural approach. It would be something like what PowerShell’s “-WhatIf” parameter gives us, but applied to API calls.

This, combined with Ajax, Sockets or whatever we want/are able to use, would give us the UX we want without compromising our architecture.

Conclusion

Think carefully about the responsibilities of the area where you’re putting validations, to see whether they fit or you’re way off the mark.

You’ve just read a post that goes on forever only to tell you a handful of trivial things. If you didn’t get much out of it, I’m sorry, I’m probably rusty at this writing thing ;)

Image and original post about Clean Architecture: https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

Mediatr, the library Vicenç mentions: https://github.com/jbogard/MediatR

A bit of validation magic for .Net: https://github.com/FluentValidation/FluentValidation/

Header photo: https://www.reddit.com/r/lotr/comments/alyty3/you_shall_not_pass_gandalf_confronting_the_balrog/