reqwest-middleware
A reqwest wrapper that adds composable client middleware chains to Rust HTTP requests.
Repository Health
Technical Analysis
reqwest-middleware is a Rust crate that wraps the popular reqwest HTTP client to support client-side middleware chains. It exposes ClientWithMiddleware, which mirrors reqwest’s own API, plus a ClientBuilder that lets you attach middleware that runs on every request in the order it was added.
The crate provides the middleware machinery but no concrete implementations itself; the same repository ships companion crates like reqwest-retry (automatic retries) and reqwest-tracing (tracing and optional OpenTelemetry). Middleware is defined by implementing an async Middleware trait with a handle method that can inspect, modify, short-circuit, or forward each request via a Next handle.
What You Get
- A ClientWithMiddleware wrapper that mirrors the reqwest client API
- A ClientBuilder for attaching ordered middleware via with()
- An async Middleware trait with a Next handle for chaining or short-circuiting
- Companion crates reqwest-retry and reqwest-tracing for ready-made behavior
Common Use Cases
- Adding automatic retries with backoff to outgoing HTTP calls
- Instrumenting requests with tracing spans and OpenTelemetry
- Injecting cross-cutting logic like auth headers, logging, or metrics on every request
Under The Hood
Architecture - The reqwest-middleware crate lives in a Cargo workspace alongside reqwest-retry and reqwest-tracing. Its src is small and focused: lib.rs documents and re-exports the API, client.rs defines ClientBuilder and ClientWithMiddleware (which delegate to an inner reqwest::Client while holding an Arc-wrapped stack of middleware), middleware.rs defines the async Middleware trait and the Next handle used to advance the chain, req_init.rs handles request initialisation, and error.rs defines the Error/Result types. Requests flow through each attached middleware in order, sharing an http::Extensions bag, until the terminal step issues the real reqwest call.
Tech Stack - Rust (edition 2018) built on reqwest 0.13, async-trait for the object-safe async trait, tower-service for service compatibility, http for shared types, and anyhow/thiserror for errors. Feature flags mirror reqwest (json, multipart, rustls, http2, stream, form, query, charset).
Code Quality - The public API is heavily documented with runnable doctests, tests use wiremock for HTTP mocking, and CI reports coverage via Coveralls. The design keeps the core middleware mechanism entirely separate from concrete implementations, which are shipped as sibling crates.
API Design - The ergonomics closely track reqwest itself: build a ClientBuilder, chain .with(middleware) calls, and .build(), after which sending requests is identical to plain reqwest. Writing middleware means implementing one async handle method, making the learning curve gentle for anyone already comfortable with reqwest and async Rust.