Introduction
Reqwest is the go-to HTTP client for Rust applications. Just as the Python requests library made HTTP simple, Reqwest brings the same ergonomics to Rust — with the added benefits of async/await, compile-time type safety, and automatic JSON serialization via Serde.
With over 12,000 GitHub stars, Reqwest is the most downloaded HTTP client on crates.io. It is used by virtually every Rust application that makes HTTP requests, from CLI tools to web scrapers to API clients.
What Reqwest Does
Reqwest handles the complete HTTP client lifecycle: building requests with headers and bodies, managing TLS connections, following redirects, handling cookies, connection pooling, timeouts, and response parsing. It supports both async (default) and blocking APIs.
Architecture Overview
[Your Rust Code]
reqwest::get(url).await?
|
[Reqwest Client]
Connection pool
Cookie jar
Redirect policy
|
[Request Builder]
Headers, body, query
JSON serialization
Form/multipart encoding
|
[hyper (HTTP engine)]
HTTP/1.1 and HTTP/2
|
[rustls or native-tls]
TLS encryption
|
[tokio (async runtime)]
Async I/OSelf-Hosting & Configuration
use reqwest::{Client, header};
use serde::{Serialize, Deserialize};
use std::time::Duration;
#[derive(Serialize)]
struct CreateUser {
name: String,
email: String,
}
#[derive(Deserialize)]
struct ApiResponse {
id: u64,
status: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a reusable client with defaults
let client = Client::builder()
.timeout(Duration::from_secs(30))
.default_headers({
let mut headers = header::HeaderMap::new();
headers.insert("Authorization", "Bearer token123".parse()?);
headers
})
.user_agent("my-app/1.0")
.build()?;
// POST with JSON body
let resp: ApiResponse = client
.post("https://api.example.com/users")
.json(&CreateUser {
name: "Alice".into(),
email: "alice@example.com".into(),
})
.send()
.await?
.json()
.await?;
// GET with query parameters
let users: Vec<User> = client
.get("https://api.example.com/users")
.query(&[("page", "1"), ("limit", "10")])
.send()
.await?
.json()
.await?;
// Download a file
let bytes = client
.get("https://example.com/file.pdf")
.send()
.await?
.bytes()
.await?;
std::fs::write("file.pdf", bytes)?;
Ok(())
}Key Features
- Async by Default — async/await API with tokio runtime
- JSON Support — automatic serialization/deserialization via Serde
- Connection Pooling — reuse connections across requests
- TLS — rustls (pure Rust) or native-tls backends
- Cookie Management — automatic cookie jar support
- Redirect Following — configurable redirect policy
- Proxy Support — HTTP, HTTPS, and SOCKS5 proxies
- Blocking API — synchronous API available via feature flag
Comparison with Similar Tools
| Feature | Reqwest | ureq | hyper | surf | requests (Python) |
|---|---|---|---|---|---|
| Async | Yes (default) | No (blocking) | Yes (low-level) | Yes | No (use httpx) |
| Ease of Use | High | Very High | Low | High | Very High |
| JSON | Built-in (Serde) | Manual | Manual | Built-in | Built-in |
| Connection Pool | Yes | Yes | Manual | Yes | Yes |
| TLS | rustls / native | rustls | Manual | Manual | Built-in |
| Best For | General HTTP | Simple scripts | Custom HTTP | async-std apps | Python |
FAQ
Q: Reqwest vs hyper — when should I use which? A: Reqwest for application-level HTTP requests (APIs, web scraping). hyper for building HTTP servers or when you need low-level control over the HTTP protocol.
Q: How do I use Reqwest without async? A: Enable the "blocking" feature: cargo add reqwest --features blocking. Then use reqwest::blocking::get() for synchronous requests.
Q: How do I handle errors? A: Reqwest returns reqwest::Error which implements std::error::Error. Use the ? operator for propagation, or match on error kinds (timeout, connection, decode, status).
Q: Does Reqwest support HTTP/2? A: Yes. Reqwest supports HTTP/2 via hyper. Enable with .http2_prior_knowledge() for known HTTP/2 servers, or let ALPN negotiate automatically with TLS.
Sources
- GitHub: https://github.com/seanmonstar/reqwest
- Documentation: https://docs.rs/reqwest
- Created by Sean McArthur (also created hyper)
- License: MIT / Apache-2.0