JSON Body in POST Using the Rust reqwest Crate
Asked Answered
V

2

10

I'm trying to implement this curl call using the Rust crate reqwest:

curl -u [USERNAME]:[PASSWORD] -H "Content-Type: application/json" -d @content.json [WEBSITE]

The file content.json encodes a JSON object as the name suggests.

My code looks like this:

fn get_response() -> Result<String, Box<dyn Error>> {
    let content = std::fs::read_to_string("content.json").unwrap();
    let client = reqwest::blocking::Client::new();
    client
        .post([WEBSITE])
        .basic_auth([USERNAME], Some([PASSWORD]))
        .json(&content)
        .send()?
        .text()?

While the curl command works, I get a "malformed request payload" error message in the response when running the Rust code. Unfortunately, I don't have control over the website, so I can't debug it there.

My question is: Am I doing something obviously wrong? If there's no obvious problem, what are some options (e.g., additional headers) that I should try out? (Of course, I already tried a few things but nothing worked)

Volitive answered 11/3, 2021 at 16:26 Comment(0)
C
11

From the documentation for .json() we can see that it expects a arbitrary serde serializable type. This indicates that what it's doing is creating JSON text from the given value. So, you're sending a JSON-quoted string containing JSON to the server, which is presumably not what it's expecting.

I haven't worked with reqwest, but it looks like for your use case with a JSON string, you would use .body() to provide the string and .header() to specify the JSON Content-Type.

Capello answered 11/3, 2021 at 19:32 Comment(2)
Thanks! You are right! I just found the answer myself (I failed to reload the page in time to see your answer). However, I did try to use .body() and set the content type header to application/json and it still did not work. So, providing a serde serializable type is the only solution that worked for me.Volitive
Note that .json() automatically inserts the Content-Type: application/json headerHarim
V
1

As it turns out, the function fn json<T: Serialize>(&mut self, json: &T) -> &mut RequestBuilder does not work as intended when the json parameter is simply a string (slice) in JSON form. When passing in a struct that contains exactly the same information as the JSON string, the code works.

Volitive answered 11/3, 2021 at 20:8 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.