Implementing a middleware in HttpClient calls

diegodrf

Diego Faria

Posted on July 19, 2024

Implementing a middleware in HttpClient calls

Intro

This article intends to show how to create a pre-request and a post-response, like a middleware, on the HttpClient.

Implementation

HttpClient accepts a HttpMessageHandler on the constructor. It allows us to modify the request behavior, including for example a pre-request and a post-response treatment. A good example is to include logs to intercept the data that is being sent and the response received just in one place or to add a required header for all requests.

Follow the implementation below:

public class CustomMessageHandler : HttpClientHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Console.WriteLine("Doing something before request.");

        var response = await base.SendAsync(request, cancellationToken);

        Console.WriteLine("Doing something after request.");

        return response;
    }
}
Enter fullscreen mode Exit fullscreen mode

We need to create a new class that inherits a HttpMessageHandler, so in this case, we inherit from HttpClientHandler that is an HttpMessageHandler. It allows us to override the SendAsync method. This method is the main method that is called to send the request. So no matter if you use GetAsync, PostAsync, etc., under the hood, the final method called is the SendAsync.

In the example above, overriding it we can put some logic before we call the base.SendAsync and we can add any logic after the response.

To implement it, we need to inject it via the constructor of the HttpClient.

using (var client = new HttpClient(new CustomMessageHandler())
{
    BaseAddress = new Uri("https://jsonplaceholder.typicode.com")
}) 
Enter fullscreen mode Exit fullscreen mode

Here is the final code:

using System.Threading.Tasks;

namespace CustomHttpClient
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            using (var client = new HttpClient(new CustomMessageHandler())
            {
                BaseAddress = new Uri("https://jsonplaceholder.typicode.com")
            }) 
            {
                var response = await client.GetStringAsync("/posts/1");

                Console.WriteLine(response);
                Console.ReadKey();
            };
        }
    }

    public class CustomMessageHandler : HttpClientHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Console.WriteLine("Doing something before request.");

            var response = await base.SendAsync(request, cancellationToken);

            Console.WriteLine("Doing something after request.");

            return response;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

And the result is what you can see below:

Doing something before request.
Doing something after request.
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Enter fullscreen mode Exit fullscreen mode

Photo by Irvan Smith on Unsplash

💖 💪 🙅 🚩
diegodrf
Diego Faria

Posted on July 19, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related