Reqwest: Biblioteca de Cliente HTTP em Rust

Reqwest é uma biblioteca de cliente HTTP de alto nível que simplifica o processo de manipulação de requisições HTTP e oferece muitos recursos comumente utilizados:

  • Suporte para APIs assíncronas e bloqueantes
  • Manipulação de vários tipos de corpos de requisição: texto simples, JSON, formulários codificados por URL, formulários multipart
  • Políticas de redirecionamento personalizáveis
  • Suporte a proxy HTTP
  • Criptografia TLS habilitada por padrão
  • Gerenciamento de cookies

Uso Básico

Realizando uma Requisição GET

Para requisições únicas, você pode usar o método conveniente get:

let body = reqwest::get("https://www.rust-lang.org")
    .await?
    .text()
    .await?;

println!("body = {body:?}");

Nota: Se você planeja fazer múltiplas requisições, é melhor criar um Client e reutilizá-lo para aproveitar o pool de conexões.

let client = reqwest::Client::new();
let res = client.get("https://www.rust-lang.org")
    .send()
    .await?;

Realizando uma Requisição POST

Você pode definir o corpo da requisição usando o método body():

let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .body("o corpo exato que é enviado")
    .send()
    .await?;

Dados de Formulário

Enviar dados de formulário é uma necessidade comum. Você pode usar qualquer tipo que possa ser serializado em dados de formulário:

// Isso enviará uma requisição POST com corpo `foo=bar&baz=quux`
let params = [("foo", "bar"), ("baz", "quux")];
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .form(&params)
    .send()
    .await?;

Dados JSON

Você pode facilmente enviar dados JSON usando o método json (requer o recurso json):

// Isso enviará uma requisição POST com corpo `{"lang":"rust","body":"json"}`
let mut map = HashMap::new();
map.insert("lang", "rust");
map.insert("body", "json");

let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .json(&map)
    .send()
    .await?;

Manipulação de Resposta

As respostas podem ser manipuladas de várias formas:

let res = client.get("https://www.rust-lang.org").send().await?;

// Obter o código de status
let status = res.status();

// Obter cabeçalhos da resposta
let content_type = res.headers().get("content-type").unwrap();

// Ler o corpo da resposta como texto
let body = res.text().await?;

// Ou analisá-lo como JSON
let json: serde_json::Value = res.json().await?;

Recursos Avançados

Política de Redirecionamento

Por padrão, o cliente lidará automaticamente com redirecionamentos HTTP, seguindo até 10 saltos. Você pode personalizar este comportamento usando ClientBuilder:

let custom_client = reqwest::Client::builder()
    .redirect(reqwest::redirect::Policy::none()) // Desabilitar redirecionamentos
    .build()?;

Suporte a Cookies

Você pode habilitar o armazenamento e envio automático de cookies de sessão via ClientBuilder:

let client = reqwest::Client::builder()
    .cookie_store(true)
    .build()?;

Configurações de Proxy

Proxies do sistema são habilitados por padrão, que procurarão configurações de proxy HTTP ou HTTPS em variáveis de ambiente:

  • HTTP_PROXY ou http_proxy: proxy para conexões HTTP
  • HTTPS_PROXY ou https_proxy: proxy para conexões HTTPS
  • ALL_PROXY ou all_proxy: proxy para ambos os tipos de conexões

Você também pode definir explicitamente um proxy via código:

let proxy = reqwest::Proxy::http("https://secure.example")?;
let client = reqwest::Client::builder()
    .proxy(proxy)
    .build()?;

// Ou desabilitar proxies
let client = reqwest::Client::builder()
    .no_proxy()
    .build()?;

Configuração TLS

O cliente usa TLS por padrão para conectar-se a destinos HTTPS:

// Adicionar certificados de servidor adicionais
let cert = reqwest::Certificate::from_pem(&cert_bytes)?;
let client = reqwest::Client::builder()
    .add_root_certificate(cert)
    .build()?;

// Configurar certificados de cliente
let identity = reqwest::Identity::from_pkcs12_der(&pkcs12_der, "password")?;
let client = reqwest::Client::builder()
    .identity(identity)
    .build()?;

Configurações de Timeout

Você pode configurar durações de timeout para requisições:

let client = reqwest::Client::builder()
    .timeout(std::time::Duration::from_secs(10))
    .build()?;

Recursos Opcionais

Reqwest oferece vários recursos opcionais que podem ser habilitados ou desabilitados via recursos do Cargo:

  • http2 (habilitado por padrão): suporte para HTTP/2
  • default-tls (habilitado por padrão): fornece suporte TLS para HTTPS
  • rustls-tls: fornece funcionalidade TLS usando rustls
  • blocking: fornece uma API de cliente bloqueante
  • json: fornece funcionalidade de serialização e desserialização JSON
  • multipart: fornece funcionalidade de formulário multipart
  • cookies: fornece suporte a sessão de cookies
  • gzip, brotli, deflate, zstd: suporte para várias descompressões de corpo de resposta
  • socks: fornece suporte a proxy SOCKS5

API Bloqueante

Quando operações assíncronas não são necessárias, você pode usar a API bloqueante (requer o recurso blocking):

let body = reqwest::blocking::get("https://www.rust-lang.org")?.text()?;

let client = reqwest::blocking::Client::new();
let res = client.post("http://httpbin.org/post")
    .json(&map)
    .send()?;