pub struct Json<T>(pub T);Expand description
A JSON extractor and responder.
Json<T> wraps any value T and grants it two complementary roles inside
a Churust handler:
§As an extractor (handler argument)
When placed as the last handler argument, Json<T> reads the entire
request body and attempts to deserialize it as JSON into T. T must
implement serde::de::DeserializeOwned.
The request must declare a JSON content type — application/json, or any
+json structured suffix. Anything else is 415 Unsupported Media Type,
which is what keeps a cross-origin HTML form (whose three possible content
types send no CORS preflight) from reaching a JSON handler with the
visitor’s cookies attached.
If the body is missing or malformed the framework returns an HTTP 400 Bad Request response automatically — the handler is never called.
use churust_core::{Churust, TestClient};
use churust_json::Json;
use serde::Deserialize;
#[derive(Deserialize)]
struct CreateUser { username: String }
let app = Churust::server()
.routing(|r| {
r.post("/users", |Json(body): Json<CreateUser>| async move {
format!("created {}", body.username)
});
})
.build();
let res = TestClient::new(app)
.post("/users")
.header("content-type", "application/json")
.body(r#"{"username":"bob"}"#)
.send()
.await;
assert_eq!(res.status().as_u16(), 200);§As a responder (return value)
Wrapping any T: Serialize in Json and returning it from a handler
serializes T to JSON and sets the Content-Type header to
application/json.
If serialization fails at runtime (extremely rare for well-formed types) the framework returns an HTTP 500 Internal Server Error.
use churust_core::{Churust, Call, TestClient};
use churust_json::Json;
use serde::Serialize;
#[derive(Serialize)]
struct Status { ok: bool }
let app = Churust::server()
.routing(|r| {
r.get("/status", |_c: Call| async { Json(Status { ok: true }) });
})
.build();
let res = TestClient::new(app).get("/status").send().await;
assert_eq!(res.status().as_u16(), 200);
assert_eq!(res.header("content-type"), Some("application/json"));§Pattern destructuring
The inner value is accessed through .0 or via pattern destructuring:
use churust_json::Json;
use serde::Deserialize;
#[derive(Deserialize, Debug, PartialEq)]
struct Point { x: f64, y: f64 }
// Pattern destructuring extracts the inner value directly.
let Json(point) = Json(Point { x: 1.0, y: 2.0 });
assert_eq!(point, Point { x: 1.0, y: 2.0 });Tuple Fields§
§0: TThe inner value being wrapped.
Access it with .0 or destructure: let Json(value) = json_wrapper;.
Trait Implementations§
Source§impl<T> IntoResponse for Json<T>where
T: Serialize,
impl<T> IntoResponse for Json<T>where
T: Serialize,
Source§fn into_response(self) -> Response
fn into_response(self) -> Response
self and produce the Response to send.