I am using reqwest to perform a GET request from https://httpbin.org.
Performing a request to a one-level json endpoint like https://httpbin.org/ip is easy
use std::collections::HashMap;
fn main() {
    let body = reqwest::blocking::get("https://httpbin.org/ip")
        .unwrap()
        .json::<HashMap<String, String>>()
        .unwrap();
    dbg!(body);
}
However Im not sure how to go about other endpoints with a multi-level JSON response. How can I make a request to a multi-level JSON endpoint in reqwest?
use std::collections::HashMap;
fn main() {
    let body = reqwest::blocking::get("https://httpbin.org/get")
        .unwrap()
        .json::<HashMap<K, V>>()
        .unwrap();
    dbg!(body);
}
                Deserializing into serde_json::Value, as @BallpointBen suggests certainly works. But in many cases, you'll then need to manually extract data from an arbitrary json value, which is tedious. There is a nicer way: deserialize into a rust struct:
struct Response { /* … */ }
let body = reqwest::blocking::get("https://httpbin.org/get?arg=blargh")
    .unwrap()
    .json::<Response>()
    .unwrap();
To make that happen, you need to explain to serde how to work with your struct, e.g. like this:
use std::{collections::HashMap, net::IpAddr};
use serde::Deserialize;
#[derive(Deserialize)]
struct Response {
    args: HashMap<String, String>,
    // I'm making headers into another struct here to show some possibilities. You can of course make it a HashMap like args
    headers: ResponseHeaders,
    origin: IpAddr,
    url: url::Url,
}
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
struct ResponseHeaders {
    accept: String,
    host: String,
    #[serde(flatten)]
    dynamic: HashMap<String, String>,
}
Deserializing into native rust structs is a bit of a rabbit hole, there's an small book on it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With