--- # quotesdb-z43c title: '[TRIAGE] HTTP client selection for integration tests — reqwest vs hyper vs ureq (tokio vs blocking)' status: completed type: task priority: high created_at: 2026-03-10T23:32:05Z updated_at: 2026-03-10T23:32:05Z --- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. HTTP client for integration tests: should we use reqwest (async, tokio), hyper (low-level), or ureq (synchronous/blocking)? 1. **reqwest** — most ergonomic, async, works well with tokio::test. Adds a heavier dependency but is widely used. 2. **hyper** — low-level, minimal dependencies. More verbose. 3. **ureq** — synchronous, no async runtime needed. Simple but requires spawning a background thread to run the server. **Chosen approach: Option 1 — `reqwest` with `#[tokio::test]`.** The API server is Axum + Tokio. `reqwest` is the idiomatic async HTTP client in this stack: - `#[tokio::test]` + `reqwest` is the standard Rust integration-testing pattern for Axum services. - `features = ["json"]` enables ergonomic `.json()` request bodies and `.json::()` response deserialization — essential for testing JSON API endpoints. - Dev-dependency only: the weight of the crate does not affect the production binary size. Options 2 (hyper) and 3 (ureq) were ruled out: - hyper 1.x has a complex, low-level API that adds boilerplate with no test-writing benefit. - ureq is synchronous; using it with an async Axum server would require spawning a background thread for the server in every test, adding avoidable setup complexity. Implementation ticket **5f5ba0** (already exists and is correctly specified) captures all necessary work: adds `reqwest = { version = "0.12", features = ["json"] }`, `tokio`, `serde_json`, and `tempfile` to `[dev-dependencies]` in `Cargo.toml`. No new ticket is required. `chore(quotesdb): resolve triage — http-client-selection-for-integration-tests-reqwest-vs-hyper`