-2

I am trying to turn a object into json with serde so I can post it reqwest. However, it doesn't seem to turn into proper json when I do what I believe I have to do.

I have the struct Order:

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Order {
    #[serde(rename = "Uic")]
    uic: i64,
    #[serde(rename = "BuySell")]
    buy_sell: String,
    #[serde(rename = "AssetType")]
    asset_type: String,
    #[serde(rename = "Amount")]
    amount: i64,
    #[serde(rename = "OrderType")]
    order_type: String,
    #[serde(rename = "OrderRelation")]
    order_relation: String,
    #[serde(rename = "ManualOrder")]
    manual_order: bool,
    #[serde(rename = "AccountKey")]
    account_key: String,
}

that I serialize and try to post to an api. When I either try to send it to the API I can see on the API (The live one gives a invalid body return, so I use Postman Mock Server to test the API call) that the body that is being sent is

{
  {
key: "{"Uic":16,"BuySell":"Buy","AssetType":"FxSpot","Amount":1000,"OrderType":"Market","OrderRelation":"StandAlone","ManualOrder":false,"AccountKey":"GfCSX|cXT0uDkDakbet8NQ" 
value: "="}"
  }
}

This is how I send it:

let body = serde_json::to_string(&order).unwrap();
let order_id = client
        .post(url)
        .headers(headers)
        .bearer_auth(access_token)
        .body(body)
        .send()
        .await?
        .text()
        //.json::<OrderPlacementResponse>()
        .await?
        ;  

    let mut file = std::fs::File::create("order.json")?;
    serde_json::to_writer_pretty(&mut file, &order)?;

At the end I save it to a file and it looks like:

{
  "Uic": 16,
  "BuySell": "Buy",
  "AssetType": "FxSpot",
  "Amount": 1000,
  "OrderType": "Market",
  "OrderRelation": "StandAlone",
  "ManualOrder": false,
  "AccountKey": "GfCSX|cXT0uDkDakbet8NQ=="
}

Which is how it should look. If I send this body to the url using Postman I get the correct response. So the error is definitely in how I make the body. I just can't figure out how to fix it.

cafce25
  • 15,907
  • 4
  • 25
  • 31
RavenMan
  • 73
  • 1
  • 8
  • 1
    The way its split on `=` into `key` and `value` makes it look like its not being parsed as something else and not JSON. Do your `headers` include `content-type: application/json`? – kmdreko Aug 24 '23 at 15:07
  • Wow, I cannot believe I didn't at all think of that. That solved my issue, thanks :) – RavenMan Aug 24 '23 at 15:10
  • You can enable the `"json"` feature flag of `reqwest`, which will provide a `.json(&order)` method that you can use instead of `.body(...)`. That way it takes care of encoding as JSON (thus you can pass an `Order` directly) and setting the header for you. – kmdreko Aug 24 '23 at 15:16

1 Answers1

1

Is the order variable really an Order? Is content-type: application/json part of the headers you use?

My first guess is that you actually serialize the body correctly, but you don't tell the other end it is json, so Postman takes the entire body and puts it in some outer json that it invents itself.

Try to add dbg!(...) around some interesting places in your code to see more of what it does, like this:

let body = serde_json::to_string(dbg!(&order)).unwrap();
let order_id = client
        .post(url)
        .headers(dbg!(headers))
        .bearer_auth(access_token)
        .body(dbg!(body))
        .send()
        .await?
        .text()
        //.json::<OrderPlacementResponse>()
        .await?
        ;  

Now you can see if the body looks as it should, and if header includes the proper content-type.

Rasmus Kaj
  • 4,224
  • 1
  • 20
  • 23
  • 1
    Yeah it was me who had forgotten all about the fact that I of course have to set it to application/json. Well thank you very much for the answer! – RavenMan Aug 24 '23 at 15:11