Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core HttpClientFactory for Multiple API Services

I've got a .Net Core project that needs to connect to around 4 different API services, I'm no expert with any of the HttpClient code, but from what I found, was that you'd generally only want to reuse one instance of your HttpClient. From what I can tell the general consensus is to use the HttpClientFactory in .Net Core by registering it in your Startup class and then requesting it using DI.

Now most of my default headers and such are all generally the same besides the BaseAddress url, how should I go about this when connecting to 4 diff API services? Should I register 4 different named clients or have one client with all the default information pre-set and then manually configure it as needed e.g. configuring the address?

General questions would be as I'm fairly new to this is, it's been said to re-use one instance of an HttpClient.

  1. If I create 4 different named clients for each API service, wouldn't this create 4 instances of the HttpClient when I call the .CreateClient() method?
  2. The .CreateClient() creates a new instance every time it's called, doesn't this defeat the purpose of having one instance of the HttpClient if say I need to make 3 different calls to one API service, each of those calls will call a .CreateClient() to establish some sort of connection and that will create 3 instances of the HttpClient?

Any help for clarity would be appreciated,

Thanks!

like image 631
SC.Cee Avatar asked Sep 09 '20 23:09

SC.Cee


1 Answers

The purpose of using IHttpClientFactory is not to reuse instances of HttpClient. Instead, it is to reuse (by pooling) instances of HttpMessageHandler (actually HttpClientHandler, which is derived from the abstract HttpMessageHandler) that is the underlying object that manages HTTP connections & sockets. This diagram from Microsoft Docs shows it well.

You were worried that frequent calls to IHttpClientFactory.CreateClient() will create the same problem as frequent calls to new HttpClient(). However, this is not the case. As explained by Microsoft docs, the reason that frequent calls to new HttpClient() will result in socket exhaustion is that this constructor will create a new instance of HttpMessageHandler:

However, the issue isn't really with HttpClient per se, but with the default constructor for HttpClient, because it creates a new concrete instance of HttpMessageHandler, which is the one that has sockets exhaustion and DNS changes issues mentioned above.

You can see from the source code of IHttpClientFactory that it does not use the parameterless constructor of HttpClient in CreateClient(). Instead, it gets the HttpMessageHandler from a pool and inject it into the created HttpClient.

Whether you are using typed or named clients, you should use the HttpClient instance as if it's a transient object: it is cheap to create and you don't need to cache it for long periods of time.

like image 196
scharnyw Avatar answered Dec 04 '22 10:12

scharnyw