Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending "application/x-www-form-urlencoded" data in place of JSON over network

Tags:

rust

serde

The definition of struct which I use to serialize over network

pub struct NetworkData {
    id: String,
    status: String,
    details: <Data Structure>,
}

Now there's a function which accepts this structure, serializes it and sends over the network.

fn send_data(data: NetworkData ...) -> ... {
    let data = serde_json::to_string(&data).expect("serialize issue");

    let mut request = Request::new(reqwest::Method::POST, url);
    *request.body_mut() = Some(data.into());

    self.inner
        .execute(request)
        ...
}

Now I want to send "x-www-form-urlencoded" data over network which should change this function as follows :-

fn send_data(data: NetworkData ...) -> ... {
    // How should I change this?????
    //let data = serde_json::to_string(&data).expect("serialize issue");

    let mut request = Request::new(reqwest::Method::POST, url);
    let content_type = HeaderValue::from_str(&format!("{}", "application/x-www-form-urlencoded",))
            .expect("Header value creation bug");
    request
        .headers_mut()
        .insert(header::CONTENT_TYPE, content_type);        
    *request.body_mut() = Some(data.into());

    self.inner
        .execute(request)
        ...
}

But how should I organize my "data" to fit into this picture.

like image 217
ravi Avatar asked Feb 03 '26 09:02

ravi


2 Answers

You can most likely use the serde_urlencoded crate in exactly the same way you did with the JSON.

I have no idea what your <Data Structure> looks like, since you haven't provided it, but the serde_urlencoded crate only supports primitive types, so if you have more fancy things, you'll have to come up with your own transformation; x-www-form-urlencoded is just a set of key=value pairs. Anyway, here's a working sample:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub struct NetworkData {
    id: String,
    status: String,
    data: u32,
}

fn main() {
    let data = NetworkData {
        id: "ID".into(),
        status: "Status".into(),
        data: 42,
    };
    let data = serde_urlencoded::to_string(&data).expect("serialize issue");

    println!("{}", data);
}

playground

like image 168
Alex Avatar answered Feb 05 '26 23:02

Alex


This has been greatly simplified as described in the documentation:

// This will POST a body of `foo=bar&baz=quux`
let params = [("foo", "bar"), ("baz", "quux")];
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .form(&params)
    .send()
    .await?;
like image 25
Jorge Leitao Avatar answered Feb 06 '26 00:02

Jorge Leitao



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!