Make nested JSON objects in Serde/Reqwest

Hello

I need to send the following JSON to an API using Reqwest:

{
	"description": "my description",
	"amount":  {
		"currency":"EUR",
		"value": "1000.00"
	},
	"redirectUrl": "https://xxx.ngrok.io/order"
}

Reqwest allows you to convert a HashMap to JSON. So I did that:

let mut params = HashMap::new();

            let mut amount = HashMap::new();
            amount.insert("currency", "EUR");
            amount.insert("value", "1000.00");

            params.insert("amount", serde_json::to_string(&amount).unwrap());
            params.insert("redirectUrl", "https:/xxx.ngrok.io/order".to_string());
            params.insert("description", "My Description".to_string());

The problem is that this is the JSON-result:

{
	"description": "My Description",
	"amount": "{\"currency\":\"EUR\",\"value\":\"1000.00\"}",
	"redirectUrl": "https://xxx.ngrok.io/order"
}

This returns a Http 422 response code from the API. And I think the exists in the amount-attribute. For some reason it makes the value a string instead of a nested JSON-object...

How can I fix this?

The json! macro is a convenient way to build a JSON value.

Or you can define a struct that matches the structure of your request format, add #[derive(Serialize)], and then serialize it to JSON.

1 Like

I decided to go with Structs instead of Hashmaps. Hashmaps do not allow nested JSON's because you can't have two different types in a Hashmap.

           #[derive(Serialize)]
            struct Amount {
                currency: String,
                value: String,
            }
            #[derive(Serialize)]
            struct Parameters {
                description: String,
                amount: Amount,
                redirectUrl: String,
            }

            let params = Parameters {
                description: "My Description".to_string(),
                amount: Amount {
                    currency: "EUR".to_string(),
                    value: "1000.00".to_string(),
                },
                redirectUrl: "https://xxx.com".to_string(),
            };

            let json = serde_json::to_string(&params).unwrap();
            println!("{}", json);