HTTP 客户端
问题
Rust 中如何发送 HTTP 请求?
答案
reqwest 是最流行的 HTTP 客户端,基于 hyper 封装。
基础用法
use reqwest::Client;
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct User {
id: u64,
name: String,
}
#[derive(Serialize)]
struct CreateUser {
name: String,
email: String,
}
async fn demo() -> reqwest::Result<()> {
// 推荐复用 Client(内置连接池)
let client = Client::new();
// GET 请求
let user: User = client
.get("https://api.example.com/users/1")
.header("Authorization", "Bearer token123")
.send()
.await?
.json() // 自动反序列化
.await?;
// POST 请求
let new_user = CreateUser {
name: "Alice".into(),
email: "alice@example.com".into(),
};
let resp = client
.post("https://api.example.com/users")
.json(&new_user) // 自动序列化
.timeout(std::time::Duration::from_secs(10))
.send()
.await?;
println!("状态码: {}", resp.status());
println!("响应体: {}", resp.text().await?);
Ok(())
}
Client 配置
use reqwest::{Client, Proxy};
use std::time::Duration;
let client = Client::builder()
.timeout(Duration::from_secs(30)) // 全局超时
.connect_timeout(Duration::from_secs(5)) // 连接超时
.pool_max_idle_per_host(10) // 连接池
.user_agent("my-app/1.0")
.default_headers({
let mut h = reqwest::header::HeaderMap::new();
h.insert("Accept", "application/json".parse().unwrap());
h
})
.build()?;
最佳实践
- 复用
Client:内置连接池和 DNS 缓存,避免每次请求都创建新连接 - 设置超时:防止请求无限挂起
- 使用
.json()而非手动序列化
常见面试问题
Q1: reqwest 和 hyper 有什么区别?
答案:
| 特性 | reqwest | hyper |
|---|---|---|
| 层级 | 高层封装 | 底层实现 |
| 易用性 | 简单 | 复杂 |
| 连接池 | 内置 | 需手动管理 |
| TLS | 内置 | 可选 |
| 适用场景 | API 调用 | 自定义 HTTP 行为 |
大多数情况用 reqwest,只有需要极致性能或完全控制 HTTP 行为时才用 hyper。