#reqwest-middleware #retry #reqwest #middleware #chain

reqwest-chain

将对任何reqwest响应应用自定义标准,决定何时以及如何重试

2个不稳定版本

0.2.0 2024年4月15日
0.1.0 2022年12月6日

#384 in 数学

Download history 305/week @ 2024-05-03 444/week @ 2024-05-10 462/week @ 2024-05-17 439/week @ 2024-05-24 932/week @ 2024-05-31 917/week @ 2024-06-07 1099/week @ 2024-06-14 779/week @ 2024-06-21 788/week @ 2024-06-28 720/week @ 2024-07-05 525/week @ 2024-07-12 802/week @ 2024-07-19 1025/week @ 2024-07-26 1035/week @ 2024-08-02 892/week @ 2024-08-09 550/week @ 2024-08-16

3,718 每月下载量

MIT 许可证

12KB
84

reqwest-chain

Crates.io docs.rs GitHub

将对任何reqwest响应应用自定义标准,决定何时以及如何重试。

reqwest-chain基于reqwest-middleware构建,让您可以专注于核心逻辑而无需编写样板代码。

用例

此crate比reqwest-retry更通用。它允许检查

  • 上次请求的结果
  • 重试链的状态
  • 中间件的全局状态

基于这些信息,它可以更新下次请求的任何方面。

如果您只需要简单的重试,应使用reqwest-retry

入门

查看tests目录以获取多个示例。

您应为中间件结构体实现Chainer。这使用chain方法在每个请求响应后做出决定

  • 如果需要另一个请求,更新上一个请求以形成链中的下一个请求,并返回Ok(None)
  • 如果响应已准备好,请将其放入Ok(Some(response))
  • 如果发生错误且无法继续,请返回Err(error)

以下是初始用例;在请求失败时刷新一些授权凭据。

use reqwest::{header::{AUTHORIZATION, HeaderValue}, StatusCode};
use reqwest_chain::{Chainer, ChainMiddleware};
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware, Error};

// Mimic some external function that returns a valid token.
fn fetch_token() -> String {
    "valid-token".to_string()
}

struct FetchTokenMiddleware;

#[async_trait::async_trait]
impl Chainer for FetchTokenMiddleware {
    // We don't need it here, but you can choose to keep track of state between
    // chained retries.
    type State = ();

    async fn chain(
        &self,
        result: Result<reqwest::Response, Error>,
        _state: &mut Self::State,
        request: &mut reqwest::Request,
    ) -> Result<Option<reqwest::Response>, Error> {
        let response = result?;
        if response.status() != StatusCode::UNAUTHORIZED {
            return Ok(Some(response))
        };
        request.headers_mut().insert(
            AUTHORIZATION,
            HeaderValue::from_str(&format!("Bearer {}", fetch_token())).expect("invalid header value"),
        );
        Ok(None)
    }
}

async fn run() {
    let client = ClientBuilder::new(reqwest::Client::new())
        .with(ChainMiddleware::new(FetchTokenMiddleware))
        .build();

    client
        .get("https://example.org")
        // If this request fails, this will be automatically retried with an
        // updated header value.
        .header(AUTHORIZATION, "Bearer expired-token")
        .send()
        .await
        .unwrap();
}

感谢

感谢该领域的先前工作,特别是

依赖项

~3–14MB
~203K SLoC