🦀

Http requests in Rust, part 1: Get and parse JSON data

2024/09/25に公開

In this article I will demonstrate how to use popular rust crates to send simple http requests to JSONPlaceholder.

Environment

In this article we will be using rustc 1.79.0 on macos.
If you need to install rust, please visit the rustup website and follow the instructions.

Crates(packages) to be used

I will be using:

cargo.toml

This is how my cargo.toml will look for reference:

[package]
name = "sending_reqwests"
version = "0.1.0"
edition = "2021"

[dependencies]
reqwest = { version = "0.12.7", features = ["json"] }
tokio = { version = "1.40.0", features = ["rt", "rt-multi-thread", "macros"] }
serde_json = "1.0.128"
serde = { version = "1.0.210", features = ["derive"] }

Sending a get request

Using reqwest::get we can send a simple get request to get a placeholder JSON response. We use the tokio::main macro on our main function to facilitate async/await execution.

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let response = reqwest::get("https://jsonplaceholder.typicode.com/todos/1")
        .await?
        .text()
        .await?;

    println!("{response}");

    Ok(())
}

Now if we run the code with cargo run, we will see that our placeholder value is logged out:

Compiling sending_reqwests v0.1.0 (/Users/*****/RustroverProjects/sending_reqwests)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.87s
Running `target/debug/sending_reqwests`
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

Parsing the JSON to a struct

First we have to create a struct that matches the format of the JSON data we expect to receive. In this case we can just look at the printed return value in the previous step and we can create a matching struct.

#[derive(serde::Deserialize, Debug)]
struct Todo {
    userId: usize,
    id: usize,
    title: String,
    completed: bool,
}

Now all we need to do is to change our code so that we deserialize the JSON string we obtain from the request and print out the struct instead.

let todo: Todo = serde_json::from_str(&response).unwrap();

println!("{todo:?}");

Now if we run the code again we can see that we were able to get the JSON data, parse it as a Todo struct, and print the struct.

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
Running `target/debug/sending_reqwests`
Todo { userId: 1, id: 1, title: "delectus aut autem", completed: false }

The end

That's it. Now you know how to get and parse JSON data using popular rust crates. In the next part of this article series (coming soon!), I will demonstrate how to post JSON data.

For reference, this is how main.rs looks when finished:

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let response = reqwest::get("https://jsonplaceholder.typicode.com/todos/1")
        .await?
        .text()
        .await?;

    let todo: Todo = serde_json::from_str(&response).unwrap();


    println!("{todo:?}");

    Ok(())
}


#[derive(serde::Deserialize, Debug)]
struct Todo {
    userId: usize,
    id: usize,
    title: String,
    completed: bool,
}

Have a nice day!

Discussion