JSON
rust-web-server ships two JSON layers:
- Built-in parser (
rust_web_server::json::object::JSON) — a zero-dependency, hand-rolled JSON parser that handles strings, numbers, booleans, null, nested objects, and arrays. No third-party crates required. Json<T>extractor / responder (rust_web_server::json::Json) — backed byserde_json; requiresfeatures = ["serde"]. Use this for typed request/response structs.
Json<T> extractor and responder (recommended)
Enable the serde feature in Cargo.toml:
[dependencies]rust-web-server = { version = "17", features = ["serde"] }serde = { version = "1", features = ["derive"] }Deserializing a request body
use serde::Deserialize;use rust_web_server::json::Json;use rust_web_server::extract::FromRequest;use rust_web_server::request::Request;use rust_web_server::response::{Response, STATUS_CODE_REASON_PHRASE};use rust_web_server::router::PathParams;use rust_web_server::server::ConnectionInfo;
#[derive(Deserialize)]struct CreatePost { title: String, body: String, tags: Vec<String>,}
fn create_post( req: &Request, _params: &PathParams, _conn: &ConnectionInfo, _state: &(),) -> Response { let Json(payload) = match Json::<CreatePost>::from_request(req) { Ok(j) => j, Err(r) => return r, // 400 Bad Request on parse failure };
println!("New post: {}", payload.title);
let mut r = Response::new(); r.status_code = *STATUS_CODE_REASON_PHRASE.n201_created.status_code; r.reason_phrase = STATUS_CODE_REASON_PHRASE.n201_created.reason_phrase.to_string(); r}Json::<T>::from_request calls serde_json::from_slice on request.body and returns a 400 Bad Request response (with a human-readable error message as the body) on any parse failure.
Json<T> also implements FromRequest directly, so it works with #[derive(FromRequest)]:
use rust_web_server::extract::FromRequest;
#[derive(rust_web_server::FromRequest)]struct Payload { body: Json<CreatePost>,}Serializing a response
use serde::Serialize;use rust_web_server::json::Json;use rust_web_server::response::Response;
#[derive(Serialize)]struct PostResponse { id: u64, title: String, slug: String,}
fn get_post( _req: &Request, params: &PathParams, _conn: &ConnectionInfo, _state: &(),) -> Response { let post = PostResponse { id: 42, title: "Hello".to_string(), slug: "hello".to_string(), };
Json(post).into_response() // Sets Content-Type: application/json and status 200 OK}Json<T>::into_response uses serde_json::to_vec. If serialisation fails (extremely rare for well-formed Serialize implementations), it returns 500 Internal Server Error.
Dereferencing
Json<T> implements Deref and DerefMut to T, so you can access fields without unwrapping:
let Json(payload) = Json::<CreatePost>::from_request(req)?;// orlet json = Json::<CreatePost>::from_request(req)?;println!("{}", json.title); // via DerefSetting Content-Type: application/json manually
When building a response by hand, set the content type through Range::get_content_range:
use rust_web_server::range::Range;use rust_web_server::mime_type::MimeType;use rust_web_server::response::{Response, STATUS_CODE_REASON_PHRASE};use rust_web_server::core::New;
let json_body = br#"{"status":"ok"}"#.to_vec();
let mut r = Response::new();r.status_code = *STATUS_CODE_REASON_PHRASE.n200_ok.status_code;r.reason_phrase = STATUS_CODE_REASON_PHRASE.n200_ok.reason_phrase.to_string();r.content_range_list = vec![ Range::get_content_range(json_body, MimeType::APPLICATION_JSON.to_string())];Built-in dynamic parser (JSON / ToJSON / FromJSON)
For cases where you cannot use serde or need to introspect JSON without a fixed schema, the built-in JSON struct in rust_web_server::json::object parses JSON into a property list.
use rust_web_server::json::object::JSON;
let raw = r#"{"name":"Alice","age":30,"active":true}"#.to_string();
let properties = JSON::parse_as_properties(raw).unwrap();for (prop, value) in &properties { match prop.property_type.as_str() { "String" => println!("{} = {:?}", prop.property_name, value.string), "i128" => println!("{} = {:?}", prop.property_name, value.i128), "bool" => println!("{} = {:?}", prop.property_name, value.bool), _ => {} }}Each parsed entry is a (JSONProperty, JSONValue) pair.
JSONProperty has:
property_name: Stringproperty_type: String— one of"String","bool","i128","f64","object","array","null"
JSONValue has optional fields for each type: .string, .bool, .i128, .f64, .object, .array, .null.
To serialise a property list back to a JSON string:
use rust_web_server::json::object::JSON;
let json_string = JSON::to_json_string(properties);The ToJSON and FromJSON traits (also in rust_web_server::json::object) provide an interface for implementing dynamic JSON serialisation on your own types without serde.
Error handling summary
| Scenario | Status | Trigger |
|---|---|---|
| Malformed JSON | 400 Bad Request | Json::<T>::from_request parse failure |
| Serialisation failure | 500 Internal Server Error | Json<T>::into_response to_vec error (rare) |