Cookbook / Requests and responses
A JSON API
Parse JSON bodies, query strings and typed path parameters, and get the right 4xx status for free.
The typed request helpers parse input and answer bad input with the correct status code, so handlers only see data that already has the right shape.
| Problem | Status |
|---|---|
:id is not a number | 400 |
Body is not application/json | 415 |
| Body is malformed JSON | 400 |
| JSON has the wrong fields | 422 |
use axeon::{Json, Server, ServerError};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct NewUser {
name: String,
age: u8,
}
#[derive(Deserialize)]
struct Search {
q: String,
page: Option<u32>,
}
fn main() {
let mut app = Server::new();
// 400 if `id` isn't a number.
app.get("/users/:id", |req| async move {
let id: u64 = req.param("id")?;
Ok::<_, ServerError>(format!("user {}", id))
});
// GET /search?q=rust&page=2
app.get("/search", |req| async move {
let search: Search = req.query_as()?;
Ok::<_, ServerError>(format!("{} (page {})", search.q, search.page.unwrap_or(1)))
});
// A status code and a body, as a tuple.
app.post("/users", |req| async move {
let user: NewUser = req.json()?;
Ok::<_, ServerError>((201, Json(user)))
});
app.listen("127.0.0.1:3000").expect("server failed to start");
}
curl -X POST http://127.0.0.1:3000/users \
-H 'content-type: application/json' \
-d '{"name":"Ada","age":36}'
curl -i -X POST http://127.0.0.1:3000/users \
-H 'content-type: application/json' \
-d '{"name":"Ada"}' # 422: the age is missing
Notes#
- When a handler's only result is
Ok(..), with no?orErr, either return the value directly or write the error type once:Ok::<_, ServerError>(..). - Also available:
req.query_param("page"),req.get_header("authorization"),req.text(),req.form(),req.form_value()andreq.remote_addr(). - For field-level checks see Validation.