When building robust APIs it it really important with validation and descriptive error messages and status codes.
In this post I am going to show you how you can get rid of duplicated code in your Request Handlers by adding MediatR behaviors to take care of validation for resource existence.
MediatR is an in-process messaging library in .NET that supports requests/responses, commands, queries, events etc. Go check it out if you haven’t.
In MediatR there is something called behaviors which allow you to build your own pipeline for requests. I use them for cross cutting concerns such as logging and validation of requests parameters.
Recently when some endpoints were developed for a microservice I struggled with duplicated code in my Request Handlers that was necessary to have in place.
To give you an example lets start with a couple of API endpoints, and also the implementation of the Request Handlers with the duplicated code.
The endpoints in this example are:
Both endpoints need to verify that the id-parameter actually matches a given group to be able to update a group / add user to a group (in my example I’m using EF Core as persistence, but you can safely ignore that).
As you can see there is an if-check for group existence in both the handlers.
How should we get rid of this duplication? Wouldn’t it be good to use some sort of “validation” here as a pre-step, so that the Request Handlers could look like this?
Thank behaviors for that! Let’s introduce an interface that both the requests: UpdateGroupRequest and AddUserToGroupRequest implement.
Then create a behavior implementation class with generic constraint to the interface defined above so that the behavior only applies to requests implementing the IGroupRequest interface.
And a registration example using Autofac:
Now we can rewrite our Request Handlers without the if statements, but still get the benefit of validation!
Lets imagine we now add a couple of more endpoints:
Add the IGroupRequest interface to your requests and you will get this feature out of the box. Pretty simple! I find this kind of approach really useful. What do you think?
We have to keep in mind that there are both some cons and pros to this approach. What I’ve found out is:
- Multiple roundtrips if you have a database that you validate the existence against.
- Validation as a separate class which might confuse some of the developers
- Cleaner code in the actual request handler
- No duplicated code scattered all over all Request Handlers that need to validate an entity’s existence
If you liked this post. You know what to do! 👏