reqwest_chain/
lib.rs

1//! Middleware to retry failed HTTP requests built on [`reqwest_middleware`].
2//!
3//! Use [`ChainMiddleware`] to retry HTTP requests under specific conditions,
4//! where custom logic is needed before the next retry attempt.
5//!
6//! ## Example
7//!
8//! ```
9//! use reqwest_chain::{Chainer, ChainMiddleware};
10//! use reqwest_middleware::reqwest::{Client, Request, Response, StatusCode};
11//! use reqwest_middleware::reqwest::header::{AUTHORIZATION, HeaderValue};
12//! use reqwest_middleware::{ClientBuilder, ClientWithMiddleware, Error};
13//!
14//! // Mimic some external function that returns a valid token.
15//! fn fetch_token() -> String {
16//!     "valid-token".to_string()
17//! }
18//!
19//! struct FetchTokenMiddleware;
20//!
21//! #[async_trait::async_trait]
22//! impl Chainer for FetchTokenMiddleware {
23//!     // We don't need it here, but you can choose to keep track of state between
24//!     // chained retries.
25//!     type State = ();
26//!
27//!     async fn chain(
28//!         &self,
29//!         result: Result<Response, Error>,
30//!         _state: &mut Self::State,
31//!         request: &mut Request,
32//!     ) -> Result<Option<Response>, Error> {
33//!         let response = result?;
34//!         if response.status() != StatusCode::UNAUTHORIZED {
35//!             return Ok(Some(response))
36//!         };
37//!         request.headers_mut().insert(
38//!             AUTHORIZATION,
39//!             HeaderValue::from_str(&format!("Bearer {}", fetch_token())).expect("invalid header value"),
40//!         );
41//!         Ok(None)
42//!     }
43//! }
44//!
45//! async fn run() {
46//!     let client = ClientBuilder::new(Client::new())
47//!         .with(ChainMiddleware::new(FetchTokenMiddleware))
48//!         .build();
49//!
50//!     client
51//!         .get("https://example.org")
52//!         // If this token is invalid, the request will be automatically retried
53//!         // with an updated token.
54//!         .header(AUTHORIZATION, "Bearer expired-token")
55//!         .send()
56//!         .await
57//!         .unwrap();
58//! }
59//! ```
60//!
61
62mod chainable;
63mod middleware;
64
65pub use chainable::{ChainMiddleware, Chainer};