Schubiduh
Schubiduh

Reputation: 3

Add HttpMessageHandler dynamically depending on API route

I have a net core 3.1 project in which I call an WebAPI. I registered 3 named clients specific for 3 different Environments, everyone with specific Authentication and specific BaseAdress, but all have same routes. The API has multiple calls that can return lots of data and in the worst case on multiple parallel requests the API throws a OutOfMemoryException. So, specific for these heavy hitting calls I wrote custom rate limiting for which I would like some ideas how to best add it to the processing pipeline.

I moved all heavy hitting API calls to a separate class, doubled the named HttpClients and added a specific MessageHandler to the doubled HttpClients.

services.AddHttpClient("KubernetesClient", (sp, client) =>
{
   // SettingBase Address and Auth token
}).AddHttpMessageHandler<CustomMessageHandler>()

I dont like it since I have to configure the same HttpClients twice, just to build a different pipeline.

I was expecting that I could reconfigure an existing HttpClient in the HttpClientFactory and add a MessageHandler when I call _httpFactory.CreatClient("KubernetesClient") in the new Class.

Upvotes: 0

Views: 404

Answers (2)

Schubiduh
Schubiduh

Reputation: 3

In the end it was more of failure in design I guess. I took the HttpClient logic for the different environments and put in different MessageHandlers. Now I have only 2 HttpClients, one for the easy calls and one for heavy load. I attach the different MessageHandlers to the HttpClients depending on the environment and the heavy load HttpClient gets an additional RateLimiterMessageHandler which throttles everything with SemaphoreSlim.

Upvotes: 0

abhi
abhi

Reputation: 1084

You can make a DelegatingHandler that determines whether to use the rate limiting logic or not based on some context since you are using named clients. When you register the named client, you can then attach this handler.

Here's an illustration:

   public class RateLimitingMessageHandler : DelegatingHandler
    {
      

  protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // Logic for determining if rate limiting should be applied
        if (ShouldApplyRateLimiting(request))
        {
            // Apply rate limiting logic here
        }

        return await base.SendAsync(request, cancellationToken);
    }

    private bool ShouldApplyRateLimiting(HttpRequestMessage request)
    {
        // Your custom logic to decide whether to rate limit or not
        return true; // or false
    }
}

Upvotes: 0

Related Questions