Request Endpoint Response (REPR) pattern in ASP.NET WEB API
WebAPI
19 Articles
In this article, let's learn about Request Endpoint Response (REPR) Pattern, a better way to organize API's and how to implement in WebAPI in ASP.NET Core.
Note: If you have not done so already, I recommend you read the article on Single Responsibility Principle in SOLID.
Table of Contents
- Introduction
- Why REPR Pattern ?
- What is REPR Pattern ?
- Implementing REPR Pattern
- Problems with REPR Pattern
- Advantages
- Summary
Introduction
I have been programming in API for a very long time and I also help companies to move out of their technical debt. I like to design and oragnize API's in a way that it is easy to maintain and scale. But I can tell you that the traditional way of organizing API's in Controllers are always a source of pain in ASP.NET projects.
ASP.NET WEB API Controllers are essentially an anti pattern. They are always fat and huge. They are collection of methods that never call one another and do not operate on same state. They are not cohesive. They tend to get bloated over the time of development. But since that is the approach which comes with the default tempate, most of the developers started to follow it.
Ofcourse you can use tools like MediatR to solve this problem. But what if I tell you that you can do it without any third party library or extra plumbing ?. Let's learn how to overcome this using REPR Pattern.
Why REPR Pattern ?
Well the answer is simple. API Endpoints are really just controllers with few constraints applied to them. They literally inherit from ControllerBase and so, its acceptable to do this way, and everything that works with Controllers, like routing, model binding, model validation, dependency injection, filters, etc. all works just fine with API Endpoints because, you might have guessed it, they're again controllers.
Yes its going to be controllers again but with Single Responsibility Principle applied to them. They are going to be small and cohesive. They are going to be easy to maintain and scale. They are going to be easy to test. They don't change often like how we add new ActionMethod to Controllers. Lesser the change in file, lesser the chances of breaking things and introducing bugs.
What is REPR Pattern ?
Usually API development follows MVC pattern. But for API's, we don't need Views. So we can remove the View part from MVC and we are left with Model-Controller. But the problem with this is that, the Controller is still fat and huge. So we need to break it down further.
Any API endpoint needs the following things to work.
- Request: The input data expected for the Enpoint
- Endpoint: The logic performed on the given Request
- Response: The output data returned from the Endpoint
Combining all these three, we get the REPR Pattern. REPR pronounced as reaper stands for Request Endpoint Response pattern. This greatly reduces the friction and makes working with individual endpoints easier.
Looking at the above folder structure, we can see that there is no traditional Controllers folder. Instead we stick to domain terms in folder naming like how we have Article folder in above image. Each Endpoint class inside the folder represents the domain function we are trying to achieve like Publish, UnPublish Article etc. This makes it more ubiquitous and easy to navigate inside codebase.
Implementing REPR Pattern
To start implementing this in new project, all you need is creating a new Controller file and inherit from ControllerBase. But if you are trying to implement this in existing project, you need to do break the ActionMethod in exisitng controller to separate controllers (i.e.) each ActionMethod will now become a Controller inheriting from ControllerBase.
The next step is to apply the necessary attributes and inject needed dependencies to the controller. The following code snippet show how it looks like.
Code Sample - Request Endpoint Response (REPR) Pattern
Problems with REPR Pattern
The common problem with REPR pattern are as follows. And fortunately we have ways to solve them.
How can we prevent some developer from adding additional ActionMethod to Endpoint in future ? Well, the answer to this is to write fitness / architecture tests. These tests will fail if someone adds additional ActionMethod to Endpoint. This is a good way to prevent developers from adding additional ActionMethod to Endpoint.
All we need to do is to Install NetArchTest.Rules NuGet package and write the following test.
Code Sample - Fitness Test for (REPR) Pattern
Each Endpoint, technically each Controller will now get listed separately in Swagger document? Yes, this is true. But fortunately we have a way to solve this. We can use Tags inside SwaggerOperation attribute to group them together. The following code snippet show how it looks like.
The above image shows the ungrouped endpoints in Swagger document. The following code snippet show how to group them together. All you need to do is to add Swashbuckle.AspNetCore.Annotations Nuget package and configure it in Program.cs as builder.Services.AddSwaggerGen(options => options.EnableAnnotations()). Then we need to add the below code snippet to endpoints.
Code Sample - Using Tags in SwaggerOperation to Group Endpoints
Tags = new[] { "ArticleEndpoints" } plays a key role. This will group all the endpoints with same tag together in Swagger document. The following image shows the grouped endpoints in Swagger document.
- Developers some time feel like they are duplicating attributes across all the Endpoints. Number of class files will increase in project. This is true. But I would say the tradeoff is worth it. We are getting a lot of benefits from this approach. And if you are using Visual Studio, you can use Code Snippets to generate the code for you.
Advantages
The advantages of REPR Pattern are as follows,
- Endpoints are more Ubiquitous and domain task/funtionality based.
- Single Responsibility and less prone to change.
- Easy to maintain and test and document.
- Easy for developers / new joiners to navigate inside codebase based on domain functionality.
- The domain intent with Endpoint becomes clearer.
Summary
In this article we learnt about REPR pattern, a better way to organize API's and how to implement in WebAPI in ASP.NET Core. We also learnt about the problems with REPR pattern and how to solve them. We also learnt about the advantages of REPR pattern. I hope you have enjoyed reading this. Now you are ready to be awesome in API development.