【问题标题】:Rust handling error response bodies with ReqwestRust 使用 Reqwest 处理错误响应体
【发布时间】:2020-04-25 16:23:15
【问题描述】:

我在我的 Rust 应用程序中使用reqwest(版本0.10.4)板条箱进行 HTTP 调用,但找不到任何关于如何处理可能返回多个可能响应体的 API 调用的示例,主要是用于错误处理。

例如,API 调用可能会以成功的 JSON 结构或以下格式的错误结构进行响应:

{
    "errors": ["..."]
}

目前我有这个函数的代码,但似乎无法弄清楚如何根据 HTTP 请求是否成功来确定我需要将响应缓冲区反序列化到哪个struct

use super::responses::{Error, Response};
use crate::clients::HttpClient;
use crate::errors::HttpError;
use reqwest::header;

pub fn call() -> Result<Response, HttpError> {
    let url = format!("{}/auth/userpass/login/{}", addr, user);
    let response = HttpClient::new()
        .post(&url)
        .header(header::ACCEPT, "application/json")
        .header(header::CONTENT_TYPE, "application/json")
        .json(&serde_json::json!({ "password": pass }))
        .send();

    match response {
        Ok(res) => {
            let payload = res.json(); // could be `Error` or `Response` but only parses to `Response`
            match payload {
                Ok(j) => Ok(j),
                Err(e) => Err(HttpError::JsonParse(e)),
            }
        }
        Err(e) => Err(HttpError::RequestFailed(e)),
    }
}

我是否遗漏了reqwest 文档中的某些内容,或者这是一个常见问题?

【问题讨论】:

    标签: rust reqwest serde-json


    【解决方案1】:

    在内部,res.json() 使用 serde_json crate 将 JSON 反序列化为您的 Rust 对象。

    在 Rust 中,当您想要一个具有多个不同变体的类型时,您可以使用枚举。 serde 为您实现了此行为,它允许您根据反序列化的格式反序列化为枚举。例如,您可以按如下方式定义响应枚举:

    #[derive(Serialize, Deserialize)]
    #[serde(untagged)]
    enum ResponseType {
      Ok(/* fields */),
      Err(/* fields */),
    }
    

    那里发生了很多事情,但这里是亮点:#[serde(untagged)] 告诉 serde 枚举应该只通过 Ok 和 Err 中的字段来区分。在您的 Rust 代码中,您可以通过变体、使用全范围的模式匹配等进行区分。

    对于您的特定用例,看起来标准的Result&lt;V, E&gt; 枚举应该足够好。

    【讨论】:

      猜你喜欢
      • 2020-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 2018-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多