Send and receive JSON

For Rust developers talking to a JSON API

You post a Rust struct as JSON and read the answer back into another struct, using serde on both ends.

Before you start

You need Rust with Cargo. fibre_http comes from crates.io:

fibre_http = "0"

Set up the project#

Start a new binary crate.

cargo new todo_client
cd todo_client

Put this in the [dependencies] section of Cargo.toml:

Cargo.toml
[dependencies]
fibre_http = { version = "0", features = ["json"] }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }

The program#

httpbin.org's /post endpoint sends back whatever JSON it received under a json field. That makes it a handy stand-in for a real API. Replace src/main.rs with this:

src/main.rs
use fibre_http::AsyncClient;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct NewTodo {
    title: String,
    done: bool,
}

#[derive(Deserialize, Debug)]
struct Echo {
    json: NewTodo,
}

#[tokio::main]
async fn main() -> Result<(), fibre_http::Error> {
    let client = AsyncClient::new();
    let todo = NewTodo { title: "write the http tutorial".to_string(), done: false };

    let response = client.post("https://httpbin.org/post").json(&todo).send().await?.error_for_status()?;
    println!("status: {}", response.status());

    let echo: Echo = response.json().await?;
    println!("the server received: {:?}", echo.json);
    Ok(())
}

Run it:

$ cargo run
status: 200 OK
the server received: NewTodo { title: "write the http tutorial", done: false }

What each part does#

json(&todo) on the request turns the struct into JSON with serde and sets Content-Type: application/json. Any type that implements Serialize works.

json() on the response reads the whole body and turns it into any type that implements Deserialize. Fields the struct does not name are skipped, which is why Echo only needs json out of httpbin's longer answer.

If the body is not valid JSON for that type, json() returns an error instead of a half-filled struct.

Where to go next#

The usage guide covers the other ways to send a body: https://github.com/excsn/fibre/blob/main/http/README.USAGE.md