Consumindo APIs REST em Aplicações Console com HttpClient no .NET

O HttpClient foi itnroduzido como a API padrão para comunicação HTTP no ecossistema .NET, substituindo as antigas classes WebRequest e HttpWebRequest. Ele oferece uma interface moderna, assíncrona e de alto desempenho. No entanto, instanciar o HttpClient diretamente de forma repetitiva pode levar à exaustão de sockets. Para resolver isso, o .NET introduz o IHttpClientFactory, que gerencia o pool de conexões e o ciclo de vida das instâncias de forma eficiente.

Neste guia, vamos configurar uma aplicação Console no .NET utilizando injeção de dependência para consumir um endpoint REST de maneira correta e escalável.

Configuração do Projeto e Dependências

Primeiro, crie um novo projeto de Console e adicione os pacotes NuGet necessários para o host genérico e injeção de dependência:

  • Microsoft.Extensions.Hosting
  • Microsoft.Extensions.Http

Configurando a Injeção de Dependência

No arquivo Program.cs, vamos configurar o host da aplicação, registrar o IHttpClientFactory e nosso serviço personalizado. O uso do Host facilita o gerenciamento do contêiner de injeção de dependência.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

// Registra o IHttpClientFactory no contêiner de serviços
builder.Services.AddHttpClient();

// Registra o serviço de consumo da API
builder.Services.AddTransient<ApiRequestService>();

using var host = builder.Build();
using var scope = host.Services.CreateScope();

// Resolve e executa o serviço
var apiService = scope.ServiceProvider.GetRequiredService<ApiRequestService>();
await apiService.FetchDataAsync();

Implementando o Serviço de Consumo

Agora, crie a classe ApiRequestService. Em vez de instanciar o HttpClient diretamente, injetamos o IHttpClientFactory através do construtor. Isso garante que as conexões TCP sejam reutilizadas adequadamente.

using System.Net.Http.Headers;

public class ApiRequestService
{
    private readonly IHttpClientFactory _httpClientFactory;

    public ApiRequestService(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    public async Task FetchDataAsync()
    {
        const string endpoint = "https://api.exemplo.com/v1/dados";
        await ExecuteGetRequestAsync(endpoint);
    }

    private async Task ExecuteGetRequestAsync(string targetUrl)
    {
        // Cria uma instância do cliente através da factory
        using var client = _httpClientFactory.CreateClient();

        // Configuração dos cabeçalhos HTTP
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("pt-BR"));
        client.DefaultRequestHeaders.ConnectionClose = false; // Mantém o keep-alive

        // Envia a requisição GET de forma assíncrona
        using var response = await client.GetAsync(targetUrl);
        
        // Garante que o status code indica sucesso (2xx)
        response.EnsureSuccessStatusCode();
        
        // Lê o conteúdo da resposta como string
        var responseBody = await response.Content.ReadAsStringAsync();

        Console.WriteLine($"Resposta recebida: {responseBody}");
    }
}

Boas Práticas com HttpClient

Ao trabalhar com comunicação HTTP no .NET, a utilização do IHttpClientFactory é altamente recomendada. Ela previne problemas de exaustão de portas (socket exhaustion) que ocorrem quanndo instâncias do HttpClient são criadas e descartadas rapidamente. Além disso, a factory permite a configuração de handlers personalizados (DelegatingHandler) para adicionar logs, políticas de retry e autenticação de forma centralizada e limpa.

Tags: dotnet CSharp httpclient dependency-injection rest-api

Publicado em 6-11 17:00 por Thomas