Sling Academy
Home/Rust/Performing HTTP GET and POST Requests in Rust Using reqwest

Performing HTTP GET and POST Requests in Rust Using reqwest

Last updated: January 06, 2025

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.

Next Article: Building a Minimal REST Client in Rust with Hyper

Previous Article: Parsing and Constructing URLs in Rust with the url Crate

Series: Networking in Rust

Rust

You May Also Like

  • E0557 in Rust: Feature Has Been Removed or Is Unavailable in the Stable Channel
  • Network Protocol Handling Concurrency in Rust with async/await
  • Using the anyhow and thiserror Crates for Better Rust Error Tests
  • Rust - Investigating partial moves when pattern matching on vector or HashMap elements
  • Rust - Handling nested or hierarchical HashMaps for complex data relationships
  • Rust - Combining multiple HashMaps by merging keys and values
  • Composing Functionality in Rust Through Multiple Trait Bounds
  • E0437 in Rust: Unexpected `#` in macro invocation or attribute
  • Integrating I/O and Networking in Rust’s Async Concurrency
  • E0178 in Rust: Conflicting implementations of the same trait for a type
  • Utilizing a Reactor Pattern in Rust for Event-Driven Architectures
  • Parallelizing CPU-Intensive Work with Rust’s rayon Crate
  • Managing WebSocket Connections in Rust for Real-Time Apps
  • Downloading Files in Rust via HTTP for CLI Tools
  • Mocking Network Calls in Rust Tests with the surf or reqwest Crates
  • Rust - Designing advanced concurrency abstractions using generic channels or locks
  • Managing code expansion in debug builds with heavy usage of generics in Rust
  • Implementing parse-from-string logic for generic numeric types in Rust
  • Rust.- Refining trait bounds at implementation time for more specialized behavior