Send a query, headers and a form

For Rust developers calling a web API that takes query parameters, headers or form posts

You add query parameters and headers to a GET request and send a form in a POST. httpbin.org echoes back what it received, so you can see exactly what went over the wire.

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 query_and_form
cd query_and_form

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

Cargo.toml
[dependencies]
fibre_http = { version = "0", features = ["json"] }
serde_json = "1"

The json feature lets you read httpbin's answer as JSON. Sending a query, headers and a form does not need it.

The program#

Replace src/main.rs with this:

src/main.rs
use fibre_http::SyncClient;
use serde_json::Value;

fn main() -> Result<(), fibre_http::Error> {
    let client = SyncClient::new();

    let echo: Value = client
        .get("https://httpbin.org/get")
        .query(&[("q", "rust http"), ("page", "2")])
        .header("accept", "application/json")
        .header("x-tutorial", "query-and-headers")
        .send()?
        .error_for_status()?
        .json()?;
    println!("url: {}", echo["url"]);
    println!("query: {}", echo["args"]);
    println!("accept: {}", echo["headers"]["Accept"]);
    println!("x-tutorial: {}", echo["headers"]["X-Tutorial"]);

    let echo: Value = client
        .post("https://httpbin.org/post")
        .form(&[("name", "fibre"), ("kind", "http")])
        .send()?
        .error_for_status()?
        .json()?;
    println!("content type: {}", echo["headers"]["Content-Type"]);
    println!("form: {}", echo["form"]);
    Ok(())
}

Run it:

$ cargo run
url: "https://httpbin.org/get?q=rust+http&page=2"
query: {"page":"2","q":"rust http"}
accept: "application/json"
x-tutorial: "query-and-headers"
content type: "application/x-www-form-urlencoded"
form: {"kind":"http","name":"fibre"}

What each part does#

query takes a list of name and value pairs. It encodes them for you, which is why the space in rust http became a + in the URL. If the URL already has a query, the new pairs go after it.

header adds one header. Call it again for each header you need.

form encodes the pairs as a form body and sets Content-Type to application/x-www-form-urlencoded. If you set your own Content-Type header first, form leaves it alone.

json() reads the body and parses it. Here it parses into serde_json::Value, so you can pick fields out by name.

Where to go next#

The next tutorial sends and receives your own Rust types as JSON. The usage guide covers raw bodies and Expect: 100-continue: https://github.com/excsn/fibre/blob/main/http/README.USAGE.md