Marcelo Daniel Toledo

Marcelo Daniel Toledo

Software Developer | Bachelor's Degree in Computer Science

Back to Projects
Cover .NET HTTP Communication
Logo .NET HTTP Communication

.NET HTTP Communication

Open Source

HTTP communication template in C# with HttpClient: from common mistakes to resilience patterns with IHttpClientFactory and Polly.

.NET C# HttpClient Polly HTTP

Context

In microservice architectures or when integrating external services, incorrect use of HttpClient is one of the most frequent errors in .NET projects. Issues like lack of connection reuse, absence of exception handling and duplicated configuration are patterns that appear repeatedly and have real production consequences.

The Problem

The starting point is a PersonService that instantiates HttpClient directly in each method: without lifecycle management, without exception handling, without centralized configuration. Each call creates a new instance, which leads to socket exhaustion and performance problems that are hard to diagnose.

public async Task<ExternalResponse<GetPersonResponse>> GetName(string name)
{
    HttpClient client = new();
    client.BaseAddress = new Uri("https://api.genderize.io");
    var response = await client.GetAsync($"/?name={name}");
    // no exception handling, no reuse
}

The Solution

The repository documents the evolution from that problematic code to a production-ready implementation, in three stages:

IHttpClientFactory with named client — centralizes configuration (base URL, timeout) in the dependency injection registration and automatically manages instance lifecycle. The service receives the factory through injection and creates clients with CreateClient().

Custom logging with HttpLoggerHandler — a custom HttpMessageHandler replaces ASP.NET’s four standard logs with two structured entries that capture method, URI, headers and body of both request and response, facilitating operational diagnostics.

Resilience with Polly — a retry policy is added (2 attempts with a 1-second interval) chained to the HttpClient via AddPolicyHandler. The logging handler and the resilience policy are composed in the same configuration:

services.AddHttpClient(HttpConstants.ClientName, client =>
{
    client.BaseAddress = new Uri(externalUrl);
    client.Timeout = TimeSpan.FromSeconds(15);
})
.AddHttpMessageHandler<HttpLoggerHandler>()
.AddPolicyHandler((IAsyncPolicy<HttpResponseMessage>)retryPolicy);

Technologies

  • .NET / ASP.NET Core — base framework and service configuration
  • C# — implementation with primary constructors and using blocks
  • IHttpClientFactory — HttpClient lifecycle management
  • Polly — resilience policies: retry with backoff
  • HttpMessageHandler — message pipeline for custom logging
  • Docker — containerization of the example