HttpClientFactory for Resilient HTTP Requests
Mind Map Summary
- Topic: HttpClientFactory for Resilient HTTP Requests
- Problems with
new HttpClient():- Socket Exhaustion: Creating a new
HttpClientfor each request can exhaust the number of available sockets. - DNS Changes:
HttpClientdoes not respect DNS changes, which can cause problems in dynamic environments.
- Socket Exhaustion: Creating a new
HttpClientFactory:- Manages
HttpClientinstances: Manages the lifetime ofHttpClientinstances to avoid the problems withnew HttpClient(). - Named and Typed Clients: Allows you to configure named and typed clients with specific settings, such as base address and default headers.
- Integration with Polly: Integrates with Polly to add resilience patterns, such as retry and circuit breaker.
- Manages
- Polly: A .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.
Practice Exercise
Use HttpClientFactory to create a typed client for an external API. Use the Polly extension to add a transient error handling policy that retries failed requests (HTTP 5xx or network errors) up to three times with an exponential backoff.
Answer
1. Typed Client:
public class MyApiClient
{
private readonly HttpClient _httpClient;
public MyApiClient(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<string> GetDataAsync()
{
var response = await _httpClient.GetAsync("/data");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
2. Configure HttpClientFactory and Polly in Program.cs:
using Polly;
using Polly.Extensions.Http;
builder.Services.AddHttpClient<MyApiClient>(client =>
{
client.BaseAddress = new Uri("https://api.example.com");
})
.AddPolicyHandler(GetRetryPolicy());
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}
Explanation:
- We create a typed client
MyApiClientthat takes anHttpClientin its constructor. - We use
AddHttpClient<MyApiClient>()to register the typed client with theHttpClientFactory. - We use
AddPolicyHandler()to add a Polly policy to the client. - The policy handles transient HTTP errors (5xx and 408) and retries the request up to three times with an exponential backoff.