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. - Полный контроль над каждым аспектом запроса.