HttpClientFactory in the Azure Cosmos DB .NET SDK
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:
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.
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:
It’s important to switch to Gateway mode because Blazor Wasm does not support TCP connections.
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.
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.