This page covers various approaches to fetching data in Rust, from REST APIs to real-time WebSocket connections and GraphQL queries.


REST API (HTTP Client)

The most popular HTTP client in Rust is reqwest. It supports both async and blocking APIs.

Setup

# Cargo.toml
[dependencies]
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"

Basic GET Request

use reqwest;
use serde::Deserialize;

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

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

POST Request with JSON Body

use reqwest::Client;
use serde::{Deserialize, Serialize};

#[derive(Serialize)]
struct NewPost {
    title: String,
    body: String,
    user_id: u32,
}

#[derive(Deserialize, Debug)]
struct PostResponse {
    id: u32,
}

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let client = Client::new();
    
    let new_post = NewPost {
        title: "My Post".to_string(),
        body: "Post content".to_string(),
        user_id: 1,
    };
    
    let response = client
        .post("<https://jsonplaceholder.typicode.com/posts>")
        .json(&new_post)
        .send()
        .await?
        .json::<PostResponse>()
        .await?;
    
    println!("Created post with id: {}", response.id);
    Ok(())
}

Using Headers & Authentication

use reqwest::{Client, header};

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let client = Client::new();
    
    let response = client
        .get("<https://api.example.com/data>")
        .header(header::AUTHORIZATION, "Bearer your_token_here")
        .header(header::CONTENT_TYPE, "application/json")
        .send()
        .await?;
    
    println!("Status: {}", response.status());
    Ok(())
}

Error Handling Pattern

use reqwest::{Client, StatusCode};

async fn fetch_data(client: &Client, url: &str) -> Result<String, Box<dyn std::error::Error>> {
    let response = client.get(url).send().await?;
    
    match response.status() {
        StatusCode::OK => Ok(response.text().await?),
        StatusCode::NOT_FOUND => Err("Resource not found".into()),
        StatusCode::UNAUTHORIZED => Err("Unauthorized".into()),
        status => Err(format!("Unexpected status: {}", status).into()),
    }
}

WebSockets

WebSockets


GraphQL

For GraphQL, use the graphql_client crate combined with reqwest.