Lesson 8 — Networking with Reqwest and Hyper
🎯 Learning Objectives
- Hiểu sự khác biệt giữa reqwest (high-level HTTP client) và hyper (low-level HTTP library).
- Biết cách gửi HTTP request cơ bản với reqwest.
- Biết cách xây dựng HTTP server đơn giản với hyper.
- Thực hành viết ứng dụng nhỏ kết hợp client + server.
✅ Explanation & Key Concepts
- Thư viện HTTP low-level, rất nhanh và linh hoạt.
- Thường dùng để viết custom server hoặc proxy.
- Client nhanh: dùng reqwest.
- Server tùy biến cao: dùng hyper.
- Có thể kết hợp (reqwest cho client, hyper cho server).
💻 Example Implementation
Cargo.toml
[package]
name = "lesson08_networking"
version = "0.1.0"
edition = "2024"
[dependencies]
reqwest = { version = "0.11"}
hyper = { version = "1", features = ["full"] }
hyper-util={ version="0.1", features=["full"] }
http-body-util="0.1"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
src/main.rs
// cargo-deps: reqwest="0.11", hyper={ version="1", features=["full"] }, hyper-util={ version="0.1", features=["full"] }, http-body-util="0.1", tokio={ version="1", features=["full"] }, serde={ version="1", features=["derive"] }, serde_json="1" use std::time::Duration; use bytes::Bytes; use http_body_util::Full; use hyper::{Request, Response}; use hyper::server::conn::http1; use hyper::service::service_fn; use hyper_util::rt::TokioIo; use tokio::net::TcpListener; use reqwest::Client; use serde::Deserialize; #[derive(Deserialize, Debug)] struct Todo { user_id: u32, id: u32, title: String, completed: bool, } async fn handle(_req: Request<hyper::body::Incoming>) -> Result<Response<Full<Bytes>>, hyper::Error> { Ok(Response::new(Full::new(Bytes::from_static( b"Hello from Hyper 1.x server!", )))) } #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { tokio::spawn(async move { let addr = "127.0.0.1:3000"; let listener = TcpListener::bind(addr).await.expect("bind"); println!("Server running on http://{addr}"); loop { let (stream, _) = listener.accept().await.expect("accept"); let io = TokioIo::new(stream); tokio::spawn(async move { let svc = service_fn(handle); if let Err(err) = http1::Builder::new().serve_connection(io, svc).await { eprintln!("server error: {err}"); } }); } }); // ---- Reqwest client fetch JSON ---- let client = Client::builder() .connect_timeout(Duration::from_secs(5)) .timeout(Duration::from_secs(15)) .build()?; let todo: Todo = client .get("https://jsonplaceholder.typicode.com/todos/1") .send() .await? .error_for_status()? // treat 4xx/5xx as errors .json() .await?; println!( "Fetched TODO #{} (user {}): '{}' — completed? {}", todo.id, todo.user_id, todo.title, todo.completed ); Ok(()) }
🛠️ Hands-on Exercises
- Basic: Dùng reqwest để fetch JSON từ API công khai và in ra trường
title. - Intermediate: Dùng hyper viết server trả JSON thay vì plain text.
- Challenge: Viết proxy mini: client gửi request tới server hyper, server gọi reqwest fetch API khác và trả kết quả.
🐞 Common Pitfalls & Debugging Tips
- Quên bật feature
jsoncho reqwest → không dùng được.json(). - Không spawn tokio runtime (
#[tokio::main]). - Hyper yêu cầu return
Result<Response<Body>, Error>; dễ sai lifetime.
🔄 Migration Notes (Rust 2024+)
- Reqwest/Hypers tương thích Rust 2024.
- Hyper v1 đang phát triển, APIs có thể thay đổi.
- Nên tách client/server code thành module riêng cho maintain dễ.
📚 References
❓ Q & A — Câu hỏi thường gặp
Q1. Khi nào nên dùng Reqwest thay vì Hyper?
- Khi bạn cần HTTP client nhanh, dễ dùng, có sẵn JSON, cookie, và async/await — dùng Reqwest. Còn Hyper phù hợp khi bạn cần tùy biến thấp tầng hoặc viết HTTP server/proxy.
Q2. Ưu và nhược điểm của high-level vs low-level API là gì?
- High-level (Reqwest) dễ dùng, tiết kiệm thời gian nhưng khó kiểm soát chi tiết; low-level (Hyper) linh hoạt và hiệu năng cao nhưng cần nhiều boilerplate và hiểu sâu về HTTP.
Q3. Làm sao để kết hợp Reqwest và Hyper trong cùng project?
- Dùng Hyper cho server-side và Reqwest cho client-side. Hai thư viện này tương thích hoàn toàn vì Reqwest được xây dựng dựa trên Hyper.
📖 Glossary of Terms
- Reqwest: HTTP client high-level dựa trên Hyper.
- Hyper: HTTP library low-level, linh hoạt, nhanh.
- ServiceFn: adapter để viết service trong Hyper.
- Body: kiểu dữ liệu đại diện cho HTTP body.
🌿 Wisdom Note
Networking abstractions cũng vậy: bề ngoài nhiều thư viện, nhưng bản chất là truyền dữ liệu qua TCP/HTTP.