We already learnt about httpclient usage. In this article we will learn about IHttpClientFactory and its best practices.
https://letsupdateskills.com/article/tips-and-tricks-for-http-client-in-net-core
Improper use of making http connection to will lead to performances issues and will degrade then performance.
There are many use cases when one API or backend application (C# console based application) need to talk with any other api then it is very important to understand the way we are making connection to other servers or api to get data.
We should be careful while opening the connection with C# code.
If we open and close http connection each and every time in requests then it will cause performance issue which we already learnt.
There are 3 main symptoms of connection pool starvation:
1. Timeouts in the form of TaskCanceledException
2. Latency spikes under load
3. Low throughput
When we make http connection using IHttpClientFactory it uses connection pooling.
Means each and every time when we need HttpClient object we will get already created object from pool and we will use it.
Cost of creating HttpClient will not be there as we are taking HttpClient object from pool itself.
The IHttpClientFactory serves as a factory abstraction that can create HttpClient instances with custom configurations.
Understanding above diagram
a. IHttptpClientFactory Injected to Clientservice
b. Inside service when we need HttpClient object we will get it from pool
c. IHttpClientFactory assigns an HttpMessageHandler from a pool to the HttpClient
d. 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 by the IHttpClientFactory to reduce resource consumption, as long as the HttpMessageHandler’s lifetime hasn’t expired.
e. We can configure the lifetime of HttpClient object also
a. Lifetime Management: We can manage lifetime for HttpClient objects.
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 per Typed Client. To override it, call SetHandlerLifetime() on the IHttpClientBuilder that’s returned when creating the client, as shown in the following code:
csharpbuilder.Services.AddHttpClient<productService>() .SetHandlerLifetime(TimeSpan.FromMinutes(5));
b. Resource Management: We can reuse http objects from pool which helps in performance improvement
c. Configuration and Policies: Using Named client we can configure multiple HttpClient object with different configurations. Named client we will discuss later in this article
d. Integration with Polly (3rd party library) : Integration with other third party libraries to make API resilient
We can use Polly and can apply circuit breaker pattern etc.
here are several ways IHttpClientFactory can be used in an app:
· Basic usage
· Named clients
· Typed clients
Basic Usage:
a. We need to inject IHttpClientFactory via DI, below is code at program.cs
builder.Services.AddHttpClient();
We need to create client from IHttpClientFactory. We need to use code like below in controller.
csharpusing HttpClient client = _iHttpClientFactory.CreateClient(); var response = await client.GetAsync(“http://google.com");
here We will get object from object pool.
Program.cs
csharpvar builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddHttpClient(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
Controller .cs
csharpusing Microsoft.AspNetCore.Mvc; using System.Net.Http; using System.Text.Json; namespace IttpclienSample12.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly ILogger<WeatherForecastController> _logger; IHttpClientFactory _iHttpClientFactory; public WeatherForecastController(ILogger<WeatherForecastController> logger, IHttpClientFactory httpClientFactory) { _logger = logger; _iHttpClientFactory = httpClientFactory; } [HttpGet(Name = "GetWeatherForecast")] public async void Get() { using HttpClient client = _iHttpClientFactory.CreateClient(); var response = await client.GetAsync("http://google.com"); } } }
We can use named client when
In application we may need multiple httpclient object with different presetup configurations
Example: in Ecommerce application we need to talk to customer api, order api then we may need to send different headers in both cases then using named client we can achieve this.
Controller
Here we have multiple named client like orderservice and customerservice.
We can configure setting at startup.cs and can use in various part of application as per requirement
This Allows you to encapsulate HTTP client configuration and logic in a strongly-typed class
We can directly use httpclient in constructor.
This can be particularly useful for consuming third-party APIs, microservices, or any HTTP-based service in a structured and maintainable way.
We can create custom class like below and can inject httpclient directly
Program.cs
in this article we have learnt how to use IHttpclientFactory to improve performance of web applications.
Copyrights © 2024 letsupdateskills All rights reserved