DEV Community

Henrique Mauri
Henrique Mauri

Posted on

HttpClientFactory no .NET 8

Reaproveitamento dos pools de conexões, reduzindo o consumo de recursos do socket, este é o resumo da utilização do HttpClientFactory no .NET.

Introdução

Não saber utilizar corretamente o HttpClient no .NET é um erro clássico, como criar várias instâncias no projeto, isso causa um acúmulo de utilização de sockets, aumentando o consumo de processamento e o famoso memory leak.

A criação de uma instância HttpClient cria internamente uma cadeia HttpMessageHandler, que é responsável por estabelecer uma conexão. Portanto, quando descartamos o HttpClient, na verdade descartamos o HttpMessageHandler, que acabará fechando a conexão. O risco é que a conexão não seja fechada assim que o cliente for descartado.

HttpMessageHandler

Uma solução para o problema acima era ter uma única instância de um HttpClient que seria compartilhada em toda aplicação.

Mas, o problema em utilizar uma única instância na solução é que as conexões seriam mantidas abertas e reutilizadas para sempre e quaisquer alterações de DNS feitas nos serviços remotos não seriam respeitadas.

Isso faria com que a aplicação apontassem para instâncias de servidor offline ou ambientes incorretos.

Apresentando a HttpClientFactory

  • O HttpClientFactory foi introduzido com .NETCore 2.1.
  • O HttpClientFactory nos dá um local central para configurar e criar HttpClients.
  • Ele gerencia o tempo de vida das cadeias HttpMessageHandler subjacentes. Ele faz isso gerenciando um pool desses MessageHandlers e mantendo-os abertos até que expirem.
  • Os MessageHandlers são mantidos ativos por no máximo 2 minutos.
  • O uso é simples e requer mudanças mínimas de código em sua aplicação.
  • Apenas chamar o método de extensão AddHttpClient no IServiceCollection oferece as vantagens do gerenciamento de instâncias pronto para uso.
  • Ele permite que você injete o HttpClientFactory em qualquer lugar da sua aplicação.

Exemplo de utilização do HttpClientFactory

O código abaixo é um exemplo de utilização do HttpClientFactory com o Polly, onde trabalharemos a resiliência.

public static class HttpClientCollectionEExtension
    {
        public static void ConfigureHttpClientService(this IServiceCollection services, IConfiguration configuration)
        {
            var retryPolicy = Policy
                .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode && r.StatusCode != HttpStatusCode.BadRequest)
                .WaitAndRetryAsync(new[]
                {
                    TimeSpan.FromSeconds(1),
                    TimeSpan.FromSeconds(3),
                    TimeSpan.FromSeconds(6)
                });

            services.AddHttpClient("taxa", c =>
            {
                c.BaseAddress = new Uri($"{configuration.GetSection("UrlApiTaxa").Value}");

                c.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
                c.DefaultRequestHeaders.Add("Keep-Alive", "3600");
                c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");

            }).AddPolicyHandler(retryPolicy);
        }
    }
Enter fullscreen mode Exit fullscreen mode

Depois de ser registrado em seu startup.cs, agora precisamos consumir este HttpClient, conforme o código de exemplo abaixo:

public class TaxaJurosExternalClient : ITaxaJurosExternalClient
    {
        public readonly IHttpClientFactory _factory;

        public TaxaJurosExternalClient(IHttpClientFactory factory)
        {
            _factory = factory;
        }

        public async Task<double> GetTaxaJuros()
        {
            var client = _factory.CreateClient("taxa");

            var result = await client.GetAsync("Get");

            var resultContent = await result.Content.ReadAsStringAsync();

            var resultObject = JsonSerializer.Deserialize<TaxaJurosOutput>(resultContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

            return resultObject.Taxa;

        }
    }
Enter fullscreen mode Exit fullscreen mode

Repare que nenhuma instância do HttpClient foi criado, simplesmente é reutilizado da nossa configuração no startup.cs, o que deixa seu código muito mais performático e organizado.

O exemplo completo de utilização do HttpClientFactory com o Polly, você confere no link abaixo:

https://github.com/hgmauri/sample-httpclientfactory-polly

Top comments (0)