HTTP-клиент для Rust: обзор лучших библиотек
Rust — язык системного программирования, который набирает популярность в веб-разработке и создании высоконагруженных сервисов. Одна из ключевых задач любого сетевого приложения — отправка HTTP-запросов. В этой статье мы рассмотрим лучшие библиотеки для работы с HTTP в Rust, их особенности, производительность и примеры использования. Материал будет полезен как новичкам, так и опытным разработчикам, выбирающим инструмент для своего проекта.
1. reqwest — универсальный выбор
reqwest — самая популярная HTTP-библиотека в экосистеме Rust. Она построена на базе hyper и tokio, но предоставляет высокоуровневый, эргономичный API. Поддерживает как асинхронный (по умолчанию), так и блокирующий режимы (через фичу blocking).
Ключевые возможности:
- Асинхронные и синхронные запросы
- Автоматическая обработка JSON (сериализация/десериализация через
serde) - Поддержка TLS, cookies, прокси
- Перенаправления и тайм-ауты
- Загрузка файлов и multipart/form-data
Пример асинхронного GET-запроса:
use reqwest;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct User {
id: u32,
name: String,
email: String,
}
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let user: User = reqwest::get("https://jsonplaceholder.typicode.com/users/1")
.await?
.json()
.await?;
println!("{:?}", user);
Ok(())
}
Пример блокирующего POST-запроса:
use reqwest::blocking::Client;
use serde_json::json;
fn main() -> Result<(), reqwest::Error> {
let client = Client::new();
let resp = client.post("https://httpbin.org/post")
.json(&json!({"key": "value"}))
.send()?;
println!("Status: {}", resp.status());
Ok(())
}
Плюсы: огромное сообщество, отличная документация, гибкость. Минусы: относительно большой размер бинарника, зависимость от tokio.
2. ureq — минималистичный синхронный клиент
ureq — лёгкая, простая библиотека без асинхронности. Идеальна для скриптов, CLI-утилит и случаев, когда не нужен tokio. Работает «из коробки» без настройки рантайма.
Особенности:
- Только синхронные запросы
- Минимальное количество зависимостей
- Поддержка HTTPS, cookies, перенаправлений
- Встроенный JSON (через фичу
json)
Пример:
use ureq;
fn main() -> Result<(), ureq::Error> {
let body: String = ureq::get("https://api.github.com/repos/rust-lang/rust")
.call()?
.into_string()?;
println!("{}", &body[..200]);
Ok(())
}
Плюсы: простота, малый вес, быстрое время компиляции. Минусы: нет асинхронности, ограниченные возможности для сложных сценариев.
3. hyper — низкоуровневая основа
hyper — это фундаментальная HTTP-библиотека для Rust, на которой построены reqwest и многие другие. Она предоставляет полный контроль над протоколом, но требует больше кода и понимания асинхронности.
Когда использовать: если вам нужна максимальная производительность, нестандартные протоколы или вы создаёте собственный HTTP-фреймворк.
Пример простого клиента:
use hyper::{Client, Uri};
use hyper::body::HttpBody as _;
use tokio;
#[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 resp = client.get(uri).await?;
while let Some(chunk) = resp.body_mut().data().await {
println!("{}", std::str::from_utf8(&chunk?)?);
}
Ok(())
}
Плюсы: максимальная гибкость и производи