Is it possible to get both the text and the JSON of a response from reqwest
Asked Answered
T

1

11

From the reqwest docs, you can get the deserialized json, or the body text from a request response.

What I can't see is how to get them both. My requirement is that I want the decoded json for use in the code but want to print out the text for debugging. Unfortunately attempting to get both will give you an error about use of a moved value since both of these functions take ownership of the request. It doesn't seem possible to clone the request either.

This is an example of something I'd like to be able to do but line 4 is invalid since it uses response which was moved on line 1.

let posts: Vec<Post> = match response.json::<PostList>().await {
    Ok(post_list) => post_list.posts,
    Err(e) => {
        let text = response.text().await.unwrap();
        println!("Error fetching posts: {}, {}", e, text);
        Vec::new()
    }
}; 
Typeset answered 30/12, 2021 at 3:56 Comment(2)
The Response::json() method is literally just getting the bytes of the response body and then calling serde_json::from_slice on that. What's stopping you from doing the same thing? Get the text(), print it, then deserialize the text as JSON.Alyworth
As an alternative, you could also just print the posts object directly, assuming it implements Debug or Display.Alyworth
H
14

The reason both json() and text() cannot be called on same response is that both these methods have to read the whole response stream, and this can only be done one time.

Your best option here is to first read it into a String and then parse JSON from that string:

let response_text = response.text().await.unwrap();
let posts: Vec<Post> = match serde_json::from_str::<PostList>(&response_text) {
  ...
}
Hartley answered 30/12, 2021 at 7:35 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.