Peter Prographo
Peter Prographo

Reputation: 1331

How to get the data the server sent back from a reqwest http call?

I have a simple http server, that expects a POST of json data. It will send back the exact same json data, but with an extra 'received' field.

I can demonstrate this using curl:

$ curl -X POST -H "Content-Type: application/json" -d '{"id":1,"jsonrpc":"2.0","method":"getNext","params":[{"flavour":"apples"}]}' http://127.0.0.1:8008
{"params": [{"flavour": "apples"}], "received": "ok", "jsonrpc": "2.0", "id": 1, "method": "getNext"}

The http server was send some json, and it replied the same json but with the extra 'received' field.

I am trying to do the exact same in rust with reqwest.

use serde_json::{Value};

#[tokio::main]
async fn main() {

    let url = "http://127.0.0.1:8008";

    let data = r#"
        {
            "id": 1,
            "jsonrpc": "2.0",
            "method": "getNext",
            "params": [ {
                "flavour": "apple"
            } ]
        }"#;

    let v: Value = match serde_json::from_str(data) {
        Err(_) => panic!("this is a terrible mistake!"),
        Ok(y) => y,
    };

    let client = reqwest::Client::new();

    let res = client.post(url)
        .json(&v)
        .send()
        .await;

    println!("{:?}",res);
}

While this does make the call, and I can see the sent json in the server log, and i can see the server sends back the json, just like with curl... I don't know who to actually get at the data in Rust. All there seems to be is an Ok that the call worked ... but how to get the json the server sent back?

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `/Users/x/RUST/projects/monitor/target/debug/monitor`
Ok(Response { url: "http://127.0.0.1:8008/", status: 200, headers: {"server": "BaseHTTP/0.3 Python/2.7.16", "date": "Fri, 29 May 2020 13:54:39 GMT", "content-type": "application/json"} })

Upvotes: 1

Views: 671

Answers (1)

Peter Prographo
Peter Prographo

Reputation: 1331

This works.

use serde_json::{Value};

#[tokio::main]
async fn main() {

    let url = "http://127.0.0.1:8008";

    let data = r#"
        {
            "id": 1,
            "jsonrpc": "2.0",
            "method": "getNext",
            "params": [ {
                "flavour": "apple"
            } ]
        }"#;

    let v: Value = match serde_json::from_str(data) {
        Err(_) => panic!("this is a terrible mistake!"),
        Ok(y) => y,
    };

    let client = reqwest::Client::new();

    let result = client.post(url)
        .json(&v)
        .send()
        .await;

    if let Ok(response) = result {
        if let Ok(text) = response.text().await {
            let result: serde_json::Result<Value> = serde_json::from_str(&text);
            if let Ok(j) = result {
                println!("received: {}, flavour still: {}", j["received"], j["params"][0]["flavour"]);
            } else {
                panic!("Could not convert text to json");
            }
        } else {
            panic!("Could not extract text from response");
        }
    } else {
        panic!("No response from server");
    }
}
    Finished dev [unoptimized + debuginfo] target(s) in 1.93s
     Running `target/debug/monitor`
received: "ok", flavour still: "apple"

Upvotes: 1

Related Questions