Reverse engineer from curl to Rust RESTful API (reqwest)?

Hello everyone

I am trying to learn Rust RESTful API. Using reqwest (unless there is something else you suggest instead?).

I have some working curl API which I would like to convert to Rust RESTful reqwest, please.

Here is documentation of some curl code: (Amadeus API, very large travel industry company).

[https://developers.amadeus.com/self-service/apis-docs/guides/authorization-262](https://Amadeus API security guide)

Below is the CURL which I would like to convert to use reqwest in Rust.

curl "https://test.api.amadeus.com/v1/security/oauth2/token"
-H "Content-Type: application/x-www-form-urlencoded"
-d "grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}"

client_id and client_secret are just strings.

Here is my first attempt:

    let client = reqwest::Client::new();
    let data = "grant_type=client_credentials&client_id=BlahBlah&client_secret=BlahSecretBlah";
    let res = client
        .post("https://test.api.amadeus.com/v1/security/oauth2/token")
        .header("Content-Type", "application/x-www-form-urlencoded")
        .body(data)
        .send()
        .await?;

    let body = res.text().await?;
    println!("2: Body={:?}", body);

Above code seems to work!

If there is a guide on-line which helps me to reverse engineer CURL to RESTful Rust, please point me in the right direction and I will read up. I am new to RESTful API, so looking for a good guide.
Amadeus sends responses all formatted as JSON, so I plan to use serde and serde_json to unpack the results but I am open to further suggestions/improvements.

If anyone is wondering why: Amadeus API does not support Rust (they support Java, .Net, Python, etc) but all their SDKs all end up using RESTful API under the covers. They do have CURL examples too. So if I know how to convert CURL syntax to Rust RESTful API syntax (get, post, headers, parameters, etc) then I am happy.

Many thanks

I'm not aware of a guide for this exactly, but it seems like you figured out how to do it for that example. Converting curl to reqwest is usually not that hard. Are there any examples you were unable to convert?

1 Like

thank you,
I am sure I will get stuck soon enough because I dont know neither curl nor RESTful API,
so I was trying to preempt trivial questions on my behalf.

Okay, well I would encourage you to ask questions here if you get stuck.

One thing to note is that the string you are creating with the grant_type, client_id and client_secret is called a query string. To build a query string in a program, I recommend that you use the serde_qs crate. You use it like this:

#[derive(Serialize)]
struct OauthBody<'a> {
    grant_type: &'a str,
    client_id: &'a str,
    client_secret: &'a str,
}

fn create_oauth_body(client_id: &str, client_secret: &str) -> Result<String, serde_qs::Error> {
    let body = OauthBody {
        grant_type: "client_credentials",
        client_id,
        client_secret,
    };
    
    serde_qs::to_string(&body)
}
let res = client
    .post("https://test.api.amadeus.com/v1/security/oauth2/token")
    .header("Content-Type", "application/x-www-form-urlencoded")
    .body(create_oauth_body("BlahBlah", "BlahSecretBlah")?)
    .send()
    .await?;

Note that this uses a &str for the fields. You can usually only do this for structs that are used for serialization only. If a struct is used for deserialization, you probably need a String instead of &str.

To build json objects, you do something very similar using the serde_json crate.

2 Likes

thank you!
Perfect, and I will use all this in my code.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.