HTTP-клиент для Rust: обзор лучших библиотек (reqwest, ureq, hyper)

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

HTTP-клиент для Rust: обзор лучших библиотек

Rust — язык системного программирования, который всё чаще используется для создания веб-сервисов, микросервисов и инструментов для работы с сетью. Выбор правильного HTTP-клиента критически важен для производительности, безопасности и удобства разработки. В этой статье мы рассмотрим три наиболее популярные библиотеки для выполнения HTTP-запросов в экосистеме Rust: reqwest, ureq и hyper. Каждая из них имеет свои сильные стороны и подходит для разных сценариев.

1. Reqwest — универсальный выбор

Reqwest — это, пожалуй, самая популярная библиотека для HTTP-запросов в Rust. Она построена на основе hyper и предоставляет высокоуровневый, эргономичный API. Поддерживает как асинхронные (через tokio), так и синхронные запросы (с включением соответствующего флага).

Ключевые особенности:

  • Асинхронный и синхронный режимы.
  • Автоматическая обработка перенаправлений.
  • Работа с JSON (сериализация/десериализация через serde).
  • Поддержка cookies, прокси, TLS.
  • Удобная работа с формами и multipart-данными.

Пример асинхронного GET-запроса:

use reqwest;
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct ApiResponse {
    userId: u32,
    id: u32,
    title: String,
    completed: bool,
}

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let url = "https://jsonplaceholder.typicode.com/todos/1";
    let response: ApiResponse = reqwest::get(url)
        .await?
        .json()
        .await?;

    println!("{:#?}", response);
    Ok(())
}

Этот пример показывает, как легко выполнить GET-запрос и десериализовать JSON-ответ в структуру. Reqwest идеально подходит для большинства проектов: от простых скриптов до крупных веб-приложений.

2. Ureq — минимализм и простота

Ureq — это лёгкий, синхронный HTTP-клиент. Его главное преимущество — минимальное количество зависимостей и отсутствие необходимости в асинхронном рантайме. Вы просто добавляете крейт и используете его. Отлично подходит для CLI-утилит, скриптов и ситуаций, где не нужна асинхронность.

Ключевые особенности:

  • Полностью синхронный (блокирующий) API.
  • Минимальное количество зависимостей (не требует tokio).
  • Встроенная поддержка JSON и cookie.
  • Простая работа с заголовками и параметрами.

Пример POST-запроса с JSON:

use ureq;
use serde::Serialize;

#[derive(Serialize)]
struct NewTodo {
    title: String,
    completed: bool,
}

fn main() -> Result<(), ureq::Error> {
    let todo = NewTodo {
        title: "Изучить Rust".into(),
        completed: false,
    };

    let response = ureq::post("https://jsonplaceholder.typicode.com/todos")
        .set("Content-Type", "application/json")
        .send_json(&todo)?;

    let status = response.status();
    let body = response.into_string()?;
    println!("Status: {}, Body: {}", status, body);
    Ok(())
}

Ureq прощает ошибки новичкам и позволяет быстро прототипировать. Однако он не подходит для высоконагруженных асинхронных систем.

3. Hyper — фундамент экосистемы

Hyper — это низкоуровневая, асинхронная библиотека, на которой построены reqwest и многие другие крейты. Она даёт полный контроль над HTTP-соединением, но требует больше кода и понимания асинхронного программирования. Используется в production-системах, где критична производительность (например, в базах данных или прокси-серверах).

Ключевые особенности:

  • Асинхронность на базе tokio.
  • Полный контроль над каждым аспектом запроса.
  • Поддержка HTTP/1.x и HTTP/2.
  • Используется как основа для других библиотек.
  • Требует ручного управления соединениями и телом запроса.

Пример простого GET-запроса с Hyper:

use hyper::{Client, Uri};
use hyper::body::HttpBody;
use tokio::io::{stdout, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box                    

Рекомендаций