HTTP-клиент для Rust: обзор лучших библиотек
Rust — системный язык программирования, который завоевал популярность благодаря безопасности, производительности и отсутствию сборщика мусора. При разработке веб-приложений, микросервисов или инструментов для работы с API часто возникает необходимость отправлять HTTP-запросы. В этой статье мы рассмотрим лучшие библиотеки для работы с HTTP в Rust, их особенности, производительность и примеры использования.
1. reqwest — самый популярный HTTP-клиент
reqwest — это высокоуровневый, удобный HTTP-клиент для Rust, построенный на базе hyper. Он поддерживает как синхронные, так и асинхронные запросы, автоматическую обработку JSON, куки, прокси и TLS.
Основные возможности:
- Поддержка async/await (требуется tokio или async-std)
- Автоматическая сериализация/десериализация JSON (через serde)
- Работа с формами, multipart, файлами
- Управление куками и сессиями
- Поддержка HTTP/2 и TLS (через native-tls или rustls)
Пример GET-запроса с reqwest:
use reqwest;
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://api.github.com/repos/rust-lang/rust")
.await?;
let body = response.text().await?;
println!("Ответ: {}", body);
Ok(())
}
Пример POST-запроса с JSON:
use reqwest;
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = reqwest::Client::new();
let payload = json!({"title": "Новая задача", "completed": false});
let response = client
.post("https://jsonplaceholder.typicode.com/todos")
.json(&payload)
.send()
.await?;
println!("Статус: {}", response.status());
Ok(())
}
2. ureq — минималистичный и быстрый
ureq — это легковесный синхронный HTTP-клиент без зависимостей от async runtime. Он идеально подходит для скриптов, CLI-утилит и проектов, где не нужна асинхронность.
Особенности:
- Чистый синхронный API
- Минимальное количество зависимостей
- Поддержка JSON, multipart, куки
- Встроенная поддержка TLS (через native-tls или rustls)
Пример с ureq:
use ureq;
fn main() -> Result<(), ureq::Error> {
let response = ureq::get("https://httpbin.org/get")
.set("Accept", "application/json")
.call()?;
let body: serde_json::Value = response.into_json()?;
println!("JSON: {}", body);
Ok(())
}
3. hyper — низкоуровневый фундамент
hyper — это асинхронная HTTP-библиотека, на которой построены многие другие клиенты (включая reqwest). Она даёт полный контроль над запросами, но требует больше кода и понимания асинхронных концепций.
Когда выбирать hyper:
- Нужна максимальная производительность
- Требуется тонкая настройка соединений
- Вы строите собственный HTTP-сервер или прокси
Пример простого GET-запроса с hyper:
use hyper::{Client, Uri};
use hyper::body::HttpBody;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let uri: Uri = "http://httpbin.org/ip".parse()?;
let mut response = client.get(uri).await?;
while let Some(chunk) = response.body_mut().data().await {
let data = chunk?;
println!("{}", String::from_utf8_lossy(&data));
}
Ok(())
}
4. actix-web-client — для экосистемы Actix
actix-web-client — это HTTP-клиент, входящий в экосистему Actix. Он оптимизирован для работы с Actix Runtime и предоставляет удобный API для асинхронных запросов.
Преимущества:
- Глубокая интеграция с Actix
- Поддержка HTTP/2, WebSocket
- Высокая производительность
Пример с actix-web-client:
use awc::Client;
#[actix_web::main]
async fn main() -> Result<(), awc::error::SendRequestError> {
let client = Client::default();
let