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
- Get the latest .NET SDK form Nuget.
- Check the .NET SDK performance tips.
- Learn more about IHttpClientFactory in ASP.NET Core applications.
- View more samples in GitHub.
0 comments