Handling JSON
Volga simplifies the process of dealing with JSON data in your web applications, both for ingesting incoming JSON payloads in requests and sending JSON responses.
Receiving JSON Data
To accept a JSON body in a request and deserialize it into a strongly-typed entity, use the Json<T> struct. Where T should be a deserializable struct, so ensure it derives from Deserialize from serde:
use volga::{App, Json, ok};
use serde::Deserialize;
#[derive(Deserialize)]
struct User {
name: String,
age: i32
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut app = App::new();
// POST /hello
// { name: "John", age: 35 }
app.map_post("/hello", |user: Json<User>| async move {
ok!("Hello {}!", user.name)
});
app.run().await
}
To test this endpoint, you can use the curl command like this:
curl -X POST "http://127.0.0.1:7878/hello" -H "Content-Type: application/json" -d '{ "name": "John", "age": 35 }'
Hello John!
Tips
You can wrap your struct fields into Option<T> as described in Optional Query Params
Sending JSON Responses
To send responses as JSON, Volga provides the ok! macro
use volga::{App, ok};
use serde::Serialize;
#[derive(Serialize)]
struct User {
name: String,
age: i32
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut app = App::new();
app.map_get("/hello", || async {
let user: User = User {
name: "John".into(),
age: 35
};
ok!(user)
});
app.run().await
}
To see the JSON response in action:
> curl http://127.0.0.1:7878/hello
{"name":"John","age":35}
Moreover, with the ok! macro you can also use the untyped JSON:
use volga::{App, ok};
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut app = App::new();
app.map_get("/hello", || async {
ok!({ name: "John", age: 35 })
});
app.run().await
}
Using Status with JSON
You can also include HTTP status codes in your JSON responses using the status! macro:
use volga::{App, status};
use serde::Serialize;
#[derive(Serialize)]
struct User {
name: String,
age: i32
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut app = App::new();
app.map_get("/hello", || async {
let user: User = User {
name: "John".into(),
age: 35
};
status!(200, user)
});
app.run().await
}
The JSON body can be coupled with standard HTTP statuses such as 200, 400, 401, 403 and others to provide clear client-side messages.
Here is the full example