عميل 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 هو