HttpClient (04.12.2022 3M) Flashcards
Add approaches: 1. Basic usage 2. Use Named Clients 3. Use Generated Clients
Why declaring and instantiating HttpClient within a using statement is not preferred?
Though this class implements IDisposable, declaring and instantiating it within a using statement is not preferred because when the HttpClient object gets disposed of, the underlying socket is not immediately released, which can lead to a socket exhaustion problem under heavy load. That issue will result in SocketException errors.
What is intended way of using HttpClient?
HttpClient is intended to be instantiated once and reused throughout the life of an application.
What is the problem of having singletone HttpClient?
In a situation where the HttpClient is instantiated as a singleton or a static object, it fails to handle the DNS changes.
How to avoid issues of socket exhausting and DNS caching?
To address the issues mentioned above and to make HttpClient instances manageable, .NET Core 2.1 introduced the IHttpClientFactory interface which can be used to configure and create HttpClient instances in an app through Dependency Injection (DI).
Do issues of socket exhausting and DNS caching relate to HttpClient directly?
No. The issues aren’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.
What two interfaces are registered while using AddHttpClient()? What is their lifetime?
IHttpClientFactory, IHttpMessageHandlerFactory. Both are singletons by default
What the purpose of IHttpClientFactory? What methods it contains?
A factory abstraction for a component that can create HttpClient instances with a custom configuration for a given logical name.
HttpClient CreateClient(string name)
Creates and configures an HttpClient instance using the configuration that corresponds to the logical name specified by name.
What the purpose of IHttpMessageHandlerFactory? What methods it contains?
A factory abstraction for a component that can create HttpMessageHandler instances with a custom configuration for a given logical name.
HttpMessageHandler CreateHandler(string name);
Creates and configures an HttpMessageHandler instance using the configuration that corresponds to the logical name specified by name.
What does default IHttpClientFactory realization provide?
- Provides a central location for naming and configuring logical HttpClient objects. ( given by abstraction of interface IHttpClientFactory)
- Manages lifetime of HttpClients and HttpMessageHandlers to avoid socket exhausting and DNS caching.
Name four ways of how you can use IHttpClientFactory in your application?
- Basic usage
- Use Named Clients
- Use Typed Clients
- Use Generated Clients
Describe the most simple way to use a typed clients approach. And type clients lifetime.
- You should create a typed client. The typed client is a class that has injectable HttpClient. For example:
class MyTypedClient
{
MyTypedClient(HttpClient httpClient) {}
}
- Register MyTypedClient in DI container:
services.AddHttpClient< MyTypedClient >()
- Use TypedClient
public MyController: ControllerBase
{
MyController(MyTypedClient typedClient) {}
}
You can also use interfaces here for example:
class MyTypedClient : IMyTypedClient
{
MyTypedClient (HttpClient httpClient) {}
}
…
services.AddHttpClient< IMyTypedClient, MyTypedClient >()
…
public MyController: ControllerBase
{
MyController(IMyTypedClient typedClient) {}
}
Typed clients are registered as transient. HttpClient instance is new for every type client instance (transient too). But HttpMessageHandler is taken from the pool to reduce resource consumption. The lifetime of HttpMessageHandler is managed by pool.
What is HttpMessageHandlers pool and how handlers are reused? What is lifetime of HttpMessageHandler? Can you configure it?
Each time you get an HttpClient object from the IHttpClientFactory, a new instance is returned. But each HttpClient uses an HttpMessageHandler that’s pooled and reused to reduce resource consumption.
The HttpMessageHandler objects in the pool have a lifetime that’s the length of time that an HttpMessageHandler instance in the pool can be reused. The default value is two minutes, but it can be overridden.
HttpMessageHandler objects in the pool are the objects that are reused by MULTIPLE HttpClient instances.
How to override HttpHandlerMessage lifetime for typed clients?
To override it, call SetHandlerLifetime() on the IHttpClientBuilder that’s returned when creating the client, as shown in the following code:
//Set 5 min as the lifetime for the HttpMessageHandler objects in the pool used for the Catalog Typed Client
services.AddHttpClient< CatalogTypedClient >()
.SetHandlerLifetime(TimeSpan.FromMinutes(5));
Each Typed Client can have its own configured handler lifetime value. Set the lifetime to InfiniteTimeSpan to disable handler expiry.
How you can preconfigure every new HttpClient instance using Typed Client approach?
You can do by calling overloading of AddHttpClient method that receives Action< HttpClient > or Action< IServiceProvider, HttpClient > as argument. For example:
services.AddHttpClient(client =>
{
client.BaseAddress = new Uri(Configuration[“BaseUrl”]);
})
Show how to add Polly policy to HttpClient using Typed Client approach.
Policy example:
static IAsyncPolicy GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}
Registration:
services.AddHttpClient< MyTypedClient >()
.AddPolicyHandler(GetRetryPolicy())