Тело запроса как структура в Rust
При создании записи клиент часто шлет тело со строкой формата. Библиотека разбирает его в структуру, если тип поддерживает разбор полей, и передает значение в обработчик.
Из корня проекта добавим крейты для полей и строки формата, как в разделе про обмен данными:
cargo add serde --features derive
cargo add serde_json
Свяжем адрес с функцией приема и вернем ту же структуру, что пришла в теле:
use axum::{Json, Router, routing::post};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct User {
name: String,
age: i32,
}
async fn create(Json(payload): Json<User>) -> Json<User> {
Json(payload)
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/user", post(create));
let listener = match tokio::net::TcpListener::bind("127.0.0.1:3000").await {
Ok(l) => l,
Err(e) => {
eprintln!("{}", e);
return;
}
};
match axum::serve(listener, app).await {
Ok(()) => {}
Err(e) => eprintln!("{}", e),
}
}
Тело {"name":"ann","age":20}
вернется тем же объектом в ответе.
Неверный формат тела даст ответ об
ошибке клиента без входа в функцию.
Можно изменить поле перед отправкой ответа и собрать новое значение:
use axum::{Json, Router, routing::post};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct User {
name: String,
age: i32,
}
async fn create(Json(payload): Json<User>) -> Json<User> {
let mut user = payload;
user.age += 1;
Json(user)
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/user", post(create));
let listener = match tokio::net::TcpListener::bind("127.0.0.1:3000").await {
Ok(l) => l,
Err(e) => {
eprintln!("{}", e);
return;
}
};
match axum::serve(listener, app).await {
Ok(()) => {}
Err(e) => eprintln!("{}", e),
}
}
Дан путь:
/note
Объявите структуру с полем text
типа строка, примите тело и верните
его без изменений.
Дано тело:
{"name":"bob","age":30}
Опишите поле age в ответе,
если обработчик увеличивает его на
единицу, как во втором примере.
Скажите, какой тип у аргумента тела и что вернет функция при корректном разборе.