Reqwest: Biblioteca Cliente HTTP de Rust

Reqwest es una biblioteca cliente HTTP de alto nivel que simplifica el proceso de manejo de solicitudes HTTP y proporciona muchas funciones de uso común:

  • Soporte para APIs asíncronas y bloqueantes
  • Manejo de varios tipos de cuerpos de solicitud: texto plano, JSON, formularios codificados en URL, formularios multiparte
  • Políticas de redirección personalizables
  • Soporte para proxy HTTP
  • Cifrado TLS habilitado por defecto
  • Gestión de cookies

Uso Básico

Realizando una Solicitud GET

Para solicitudes individuales, puedes usar el método conveniente get:

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

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

Nota: Si planeas realizar múltiples solicitudes, es mejor crear un Client y reutilizarlo para aprovechar el agrupamiento de conexiones.

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

Realizando una Solicitud POST

Puedes establecer el cuerpo de la solicitud usando el método body():

let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .body("el cuerpo exacto que se envía")
    .send()
    .await?;

Datos de Formulario

Enviar datos de formulario es un requisito común. Puedes usar cualquier tipo que pueda serializarse en datos de formulario:

// Esto enviará una solicitud POST con un cuerpo de `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?;

Datos JSON

Puedes enviar fácilmente datos JSON usando el método json (requiere la función json):

// Esto enviará una solicitud POST con un cuerpo de `{"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?;

Manejo de Respuestas

Las respuestas pueden manejarse de varias formas:

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

// Obtener el código de estado
let status = res.status();

// Obtener encabezados de respuesta
let content_type = res.headers().get("content-type").unwrap();

// Leer el cuerpo de la respuesta como texto
let body = res.text().await?;

// O parsearlo como JSON
let json: serde_json::Value = res.json().await?;

Características Avanzadas

Política de Redirección

Por defecto, el cliente manejará automáticamente las redirecciones HTTP, siguiendo hasta 10 saltos. Puedes personalizar este comportamiento usando ClientBuilder:

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

Soporte de Cookies

Puedes habilitar el almacenamiento y envío automático de cookies de sesión a través de ClientBuilder:

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

Configuración de Proxy

Los proxies del sistema están habilitados por defecto, que buscarán configuraciones de proxy HTTP o HTTPS en variables de entorno:

  • HTTP_PROXY o http_proxy: proxy para conexiones HTTP
  • HTTPS_PROXY o https_proxy: proxy para conexiones HTTPS
  • ALL_PROXY o all_proxy: proxy para ambos tipos de conexiones

También puedes establecer explícitamente un proxy mediante código:

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

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

Configuración TLS

El cliente usa TLS por defecto para conectarse a destinos HTTPS:

// Agregar certificados de servidor adicionales
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()?;

Configuración de Tiempo de Espera

Puedes configurar duraciones de tiempo de espera para las solicitudes:

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

Características Opcionales

Reqwest proporciona varias características opcionales que pueden habilitarse o deshabilitarse a través de funciones de Cargo:

  • http2 (habilitado por defecto): soporte para HTTP/2
  • default-tls (habilitado por defecto): proporciona soporte TLS para HTTPS
  • rustls-tls: proporciona funcionalidad TLS usando rustls
  • blocking: proporciona una API de cliente bloqueante
  • json: proporciona funcionalidad de serialización y deserialización JSON
  • multipart: proporciona funcionalidad de formulario multiparte
  • cookies: proporciona soporte de sesión de cookies
  • gzip, brotli, deflate, zstd: soporte para varias descompresiones de cuerpo de respuesta
  • socks: proporciona soporte para proxy SOCKS5

API Bloqueante

Cuando no se necesitan operaciones asíncronas, puedes usar la API bloqueante (requiere la función 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()?;