Rust is a modern programming language that is increasingly being used in various domains including network programming. One of the most common tasks in networking is making HTTP requests. In Rust, the reqwest crate is a popular and convenient choice for performing these operations. In this article, we will explore how to perform HTTP GET and POST requests using reqwest in Rust.

Setting Up Your Rust Project

Before delving into requests, first, we need to set up a new Rust project. You can do this by executing the following command in your terminal:

cargo new reqwest_example

This command creates a new directory named reqwest_example with a basic Rust project setup. Next, you need to add reqwest to your Cargo.toml file as a dependency:

[dependencies]
reqwest = { version = "0.11", features = ["json"] }

Using the json feature enables easy handling of JSON data, which will be particularly useful for our examples.

Performing an HTTP GET Request

HTTP GET requests are used to retrieve data from a server at the specified resource. Let’s see how we can make a GET request using reqwest:

use reqwest::Error;

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

    println!("{}", response);
    Ok(())
}

In the code above:

  • We use reqwest::get to perform the GET request to a remote API.
  • The await keyword is used as the request execution is asynchronous.
  • We call text() to extract the response body as a string.
  • The response is printed to the console.

Handling Errors and JSON Data

In real-world applications, you'll need to handle errors gracefully and probably deal with JSON data more often. Here’s an example that fetches data and deserializes JSON into a struct.

use serde::Deserialize;
use reqwest::Error;

#[derive(Deserialize, Debug)]
struct Post {
    userId: u32,
    id: u32,
    title: String,
    body: String,
}

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

    println!("{:?}", response);
    Ok(())
}

Here, we define a Post struct that mirrors the JSON structure we expect from the server. With the serde crate, Rust can automatically deserialize JSON into this struct.

Performing an HTTP POST Request

POST requests are used to send data to a server to create or update a resource. Here’s how to perform a POST request with reqwest:


use serde_json::json;
use reqwest::Client;

#[tokio::main]
async fn main() -> Result<(), Error> {
    let client = Client::new();
    let res = client.post("https://jsonplaceholder.typicode.com/posts")
        .json(&json!({"title": "foo", "body": "bar", "userId": 1}))
        .send()
        .await?;

    println!("{:?}", res.text().await?);
    Ok(())
}

For the POST request:

  • We use a Client instance from reqwest, which offers more configuration options.
  • JSON data is sent using the json method and serde_json::json macro.
  • The response is awaited and printed.

Conclusion

The reqwest crate is a powerful tool for making HTTP requests in Rust. This article covered the basic usage of making GET and POST requests. Understanding these concepts opens up opportunities to build web clients, consume APIs, and more within Rust applications. By practicing and experimenting, you will become more proficient in handling network operations using Rust.