HttpClientFactory in the Azure Cosmos DB .NET SDK

This post has been republished via RSS; it originally appeared at: Microsoft Developer Blogs.

You might already be familiar (and if not, you should) with this famous post called "You're using HttpClient wrong" and how it is important to reuse connections across the lifetime of your application. Recently, the V3 .NET SDK has added a feature called HttpClientFactory as part of the CosmosClientOptions, which is used to customize the client instance and enables HTTP connection sharing between the SDK client and other clients within the same application. How? Let's see!

First things first

If you are reading this post, you either detected a scenario where your application is using a lot of connections (and it's causing issues on your environment), or you are trying to optimize because, well, we all like when things are tidier.

So the first thing you need to verify is that you only have one SDK client for the entire lifetime of the application. Dependency Injection frameworks make this very easy these days, if you use ASP.NET Core for example, it's as simple as registering it when configuring your services:

https://gist.github.com/ealsur/ea583996ec32ee0cbcc4683db6c3b42a

If you don't use Dependency Injection frameworks, you could opt for having static variables. Just make sure that whatever you do, there is only a single instance (be careful with Repository Patterns that create client instances internally!).

This sounds similar to IHttpClientFactory in .NET

And the reason for that is because the HttpClientFactory feature was initially designed to work alongside the IHttpClientFactory provided by ASP.NET Core. This allows the application to centralize the creation of HttpClients and, therefore, allow consumers to reuse already existing connections. 

When designing the feature, we aligned it with the IHttpClientFactory.CreateClient method, to make it easier for developers to leverage.

https://gist.github.com/ealsur/491bbbe78e5349d6f0ff3bb3fd051515

Blazor Wasm support

In Blazor Wasm applications, HTTP requests are handled by the browser, that is why the recommendation is to leverage IHttpClientFactory. With the below code, we are wiring the SDK client to use the browser for all its data transport operations:

https://gist.github.com/ealsur/d435fe063469fe09235e6d9e9eb81315

 

It's important to switch to Gateway mode because Blazor Wasm  does not support TCP connections.

Sharing HttpClients

What if your application uses the SDK client, but also other HttpClients (maybe you do calls to a REST API), or have other service clients that also use HttpClient, or you are using Resource Tokens to authenticate with Cosmos DB?

In those cases, instead of using the IHttpClientFactory, you create new HttpClient instances for each service that needs it, but reuse a SocketsHttpHandler instance for all of them.

https://gist.github.com/ealsur/87103ca1ccc10b16bde2d44483a937ce

There are two keys here:

  • Maintain a single SocketsHttpHandler instance and share it.
  • Create the HttpClient with the disposeHandler parameter as false.

This is also documented as one of the alternatives for environments that do not have access to IHttpClientFactory.

More resources

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.