Cliente HTTP em C#: fazendo requisições de forma correta e eficiente

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Por que Você Precisa de um Cliente HTTP Adequado em C#

No desenvolvimento moderno, quase nenhum aplicativo pode funcionar sem interagir com serviços externos. Seja enviando dados para um servidor, obtendo taxas de câmbio ou trabalhando com uma API na nuvem — tudo isso requer uma implementação adequada de requisições HTTP. No ecossistema C# (.NET), a principal ferramenta para esta tarefa é a classe HttpClient. No entanto, muitos desenvolvedores, especialmente iniciantes, cometem erros típicos: criar uma nova instância de HttpClient para cada requisição, esquecer de tratar exceções ou trabalhar incorretamente com assincronia.

Neste artigo, vamos detalhar como organizar corretamente um cliente HTTP em C#, verificar o envio de requisições GET e POST, trabalhar com cabeçalhos e corpo da requisição, além das melhores práticas para tratamento de erros. Após a leitura, você será capaz de escrever código confiável e eficiente para interagir com qualquer API REST.



Fundamentos do Trabalho com HttpClient em C#

A classe HttpClient faz parte do namespace System.Net.Http e está disponível em todas as versões modernas do .NET (Core, 5, 6, 7, 8 e superiores). Sua principal vantagem é o suporte a operações assíncronas e gerenciamento automático de pool de conexões.



Criando um HttpClient Corretamente

A regra mais importante: não crie um novo HttpClient para cada requisição. Isso pode levar ao esgotamento de sockets. Em vez disso, use uma única instância durante todo o ciclo de vida do aplicativo ou use IHttpClientFactory.

// ❌ Ruim: novo HttpClient para cada requisiçãousing (var client = new HttpClient()){    var response = await client.GetAsync("https://api.example.com");}

// ✅ Bom: um HttpClient para todas as requisiçõespublic class MyHttpService{ private static readonly HttpClient _client = new HttpClient(); public async Task<string> GetDataAsync(string url) { return await _client.GetStringAsync(url); }}


Configuração Básica

Ao inicializar o HttpClient, você pode definir um endereço base, timeouts e cabeçalhos padrão:

public class ApiClient{    private readonly HttpClient _httpClient;        public ApiClient()    {        _httpClient = new HttpClient        {            BaseAddress = new Uri("https://api.pythonlib.ru/"),            Timeout = TimeSpan.FromSeconds(10)        };                // Cabeçalhos que serão enviados em todas as requisições        _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");        _httpClient.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");    }}


Enviando Requisições GET e POST

Vamos analisar os dois tipos mais comuns de requisições HTTP: obter dados (GET) e enviar dados (POST).



Requisição GET: Obtendo Dados

Uma requisição GET é usada para ler dados do servidor. Ela não deve alterar o estado do recurso e não contém corpo.

public async Task<string> GetUserAsync(int userId){    try    {        var response = await _httpClient.GetAsync($"/api/users/{userId}");        response.EnsureSuccessStatusCode(); // Lançará uma exceção em caso de erro        return await response.Content.ReadAsStringAsync();    }    catch (HttpRequestException ex)    {        Console.WriteLine($"Erro na requisição: {ex.Message}");        throw;    }}

Para casos simples, você pode usar a forma abreviada:

string json = await _httpClient.GetStringAsync("/api/users/42");


Requisição POST: Enviando Dados

Uma requisição POST é usada para criar novos recursos. Os dados são enviados no corpo da requisição, geralmente no formato JSON.

public async Task<User> CreateUserAsync(User newUser){    // Serializa o objeto para JSON    var json = JsonSerializer.Serialize(newUser);                

Blogs

Book Recommendations