â
What is HttpClient?
HttpClient is a built-in class in .NET used to send HTTP requests and receive HTTP responses from web APIs.
â Why is it used?
You use HttpClient to:
-
ð Call external APIs or services
-
ðĨ Get data from a URL (like JSON)
-
ðĪ Send data (like POST, PUT requests)
-
ð Communicate over the internet (HTTP/HTTPS)
â Simple Example:
var client = new HttpClient();
var response = await client.GetStringAsync("https://api.example.com/data");
Console.WriteLine(response);â
Why Not Use new HttpClient() Directly?
Using new HttpClient() in every request can cause:
-
Socket exhaustion (sockets are not released quickly).
-
Hard-to-test code.
-
No built-in support for resilience libraries like Polly.
ð§ 1. IHttpClientFactory (Basic Usage)
â Best for:
-
Creating
HttpClientinstances on demand. -
Having control over how the client is configured at runtime.
ðĄ Example:
Startup.cs / Program.cs
builder.Services.AddHttpClient();Usage in a service:
public class MyService
{
private readonly IHttpClientFactory _httpClientFactory;
public MyService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<string> GetDataAsync()
{
var client = _httpClientFactory.CreateClient();
return await client.GetStringAsync("https://api.example.com/data");
}
}ð·ïļ 2. Named HttpClient
â Best for:
-
Calling multiple APIs with different configurations.
-
Centralizing configs (like base address, headers).
ðĄ Example:
Startup.cs / Program.cs
builder.Services.AddHttpClient("GitHubClient", client =>
{
client.BaseAddress = new Uri("https://api.github.com/");
client.DefaultRequestHeaders.UserAgent.ParseAdd("HttpClientFactory-Sample");
});Usage:
var client = _httpClientFactory.CreateClient("GitHubClient");
var response = await client.GetStringAsync("/users/octocat");ðĻâðŧ 3. Typed HttpClient
â Best for:
-
Clean Dependency Injection (DI).
-
Testable services.
-
Automatically injects preconfigured
HttpClient.
ðĄ Example:
Typed client class:
public class GitHubService
{
private readonly HttpClient _client;
public GitHubService(HttpClient client)
{
_client = client;
_client.BaseAddress = new Uri("https://api.github.com/");
_client.DefaultRequestHeaders.UserAgent.ParseAdd("HttpClientFactory-Sample");
}
public async Task<string> GetUserAsync(string username)
{
return await _client.GetStringAsync($"/users/{username}");
}
}Register it:
builder.Services.AddHttpClient<GitHubService>();Usage:
var result = await _gitHubService.GetUserAsync("octocat");ð§ 4. Refit (Type-safe REST Client)
â Best for:
-
Declarative API definitions.
-
Auto-generates HTTP logic from interfaces.
-
Great with Polly, testability, and clean architecture.
ðĄ Install:
dotnet add package Refit.HttpClientFactoryDefine interface:
public interface IGitHubApi
{
[Get("/users/{username}")]
Task<User> GetUserAsync(string username);
}Register with Refit:
builder.Services.AddRefitClient<IGitHubApi>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.github.com/"));Usage:
var user = await _gitHubApi.GetUserAsync("octocat");â Summary Table
| Method | Best For | Factory Access Needed | Testable |
|---|---|---|---|
IHttpClientFactory | Flexible, low-level usage | â Yes | ð |
Named HttpClient | Multiple APIs with different settings | â Yes | ð |
Typed HttpClient | DI-friendly, clean architecture | â No | ðð |
| Refit | Interface-based, declarative HTTP calls | â No (hidden under hood) | ððð |