rocket/serde/json.rs
1//! Automatic JSON (de)serialization support.
2//!
3//! See [`Json`] for details.
4//!
5//! # Enabling
6//!
7//! This module is only available when the `json` feature is enabled. Enable it
8//! in `Cargo.toml` as follows:
9//!
10//! ```toml
11//! [dependencies.rocket]
12//! version = "0.6.0-dev"
13//! features = ["json"]
14//! ```
15//!
16//! # Testing
17//!
18//! The [`LocalRequest`] and [`LocalResponse`] types provide [`json()`] and
19//! [`into_json()`] methods to create a request with serialized JSON and
20//! deserialize a response as JSON, respectively.
21//!
22//! [`LocalRequest`]: crate::local::blocking::LocalRequest
23//! [`LocalResponse`]: crate::local::blocking::LocalResponse
24//! [`json()`]: crate::local::blocking::LocalRequest::json()
25//! [`into_json()`]: crate::local::blocking::LocalResponse::into_json()
26
27use std::{io, fmt, error};
28use std::ops::{Deref, DerefMut};
29
30use crate::request::{Request, local_cache};
31use crate::data::{Limits, Data, FromData, Outcome};
32use crate::response::{self, Responder, content};
33use crate::form::prelude as form;
34use crate::http::uri::fmt::{UriDisplay, FromUriParam, Query, Formatter as UriFormatter};
35use crate::http::Status;
36
37use serde::{Serialize, Deserialize};
38
39#[doc(hidden)]
40pub use serde_json;
41
42/// The JSON guard: easily consume and return JSON.
43///
44/// ## Sending JSON
45///
46/// To respond with serialized JSON data, return a `Json<T>` type, where `T`
47/// implements [`Serialize`] from [`serde`]. The content type of the response is
48/// set to `application/json` automatically.
49///
50/// ```rust
51/// # #[macro_use] extern crate rocket;
52/// # type User = usize;
53/// use rocket::serde::json::Json;
54///
55/// #[get("/users/<id>")]
56/// fn user(id: usize) -> Json<User> {
57/// let user_from_id = User::from(id);
58/// /* ... */
59/// Json(user_from_id)
60/// }
61/// ```
62///
63/// ## Receiving JSON
64///
65/// `Json` is both a data guard and a form guard.
66///
67/// ### Data Guard
68///
69/// To deserialize request body data as JSON , add a `data` route argument with
70/// a target type of `Json<T>`, where `T` is some type you'd like to parse from
71/// JSON. `T` must implement [`serde::Deserialize`].
72///
73/// ```rust
74/// # #[macro_use] extern crate rocket;
75/// # type User = usize;
76/// use rocket::serde::json::Json;
77///
78/// #[post("/user", format = "json", data = "<user>")]
79/// fn new_user(user: Json<User>) {
80/// /* ... */
81/// }
82/// ```
83///
84/// You don't _need_ to use `format = "json"`, but it _may_ be what you want.
85/// Using `format = json` means that any request that doesn't specify
86/// "application/json" as its `Content-Type` header value will not be routed to
87/// the handler.
88///
89/// ### Form Guard
90///
91/// `Json<T>`, as a form guard, accepts value and data fields and parses the
92/// data as a `T`. Simple use `Json<T>`:
93///
94/// ```rust
95/// # #[macro_use] extern crate rocket;
96/// # type Metadata = usize;
97/// use rocket::form::{Form, FromForm};
98/// use rocket::serde::json::Json;
99///
100/// #[derive(FromForm)]
101/// struct User<'r> {
102/// name: &'r str,
103/// metadata: Json<Metadata>
104/// }
105///
106/// #[post("/user", data = "<form>")]
107/// fn new_user(form: Form<User<'_>>) {
108/// /* ... */
109/// }
110/// ```
111///
112/// ### Incoming Data Limits
113///
114/// The default size limit for incoming JSON data is 1MiB. Setting a limit
115/// protects your application from denial of service (DoS) attacks and from
116/// resource exhaustion through high memory consumption. The limit can be
117/// increased by setting the `limits.json` configuration parameter. For
118/// instance, to increase the JSON limit to 5MiB for all environments, you may
119/// add the following to your `Rocket.toml`:
120///
121/// ```toml
122/// [global.limits]
123/// json = 5242880
124/// ```
125#[repr(transparent)]
126#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
127pub struct Json<T>(pub T);
128
129/// Error returned by the [`Json`] guard when JSON deserialization fails.
130#[derive(Debug)]
131pub enum Error<'a> {
132 /// An I/O error occurred while reading the incoming request data.
133 Io(io::Error),
134
135 /// The client's data was received successfully but failed to parse as valid
136 /// JSON or as the requested type. The `&str` value in `.0` is the raw data
137 /// received from the user, while the `Error` in `.1` is the deserialization
138 /// error from `serde`.
139 Parse(&'a str, serde_json::error::Error),
140}
141
142impl<'a> fmt::Display for Error<'a> {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 match self {
145 Self::Io(err) => write!(f, "i/o error: {}", err),
146 Self::Parse(_, err) => write!(f, "parse error: {}", err),
147 }
148 }
149}
150
151impl<'a> error::Error for Error<'a> {
152 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
153 match self {
154 Self::Io(err) => Some(err),
155 Self::Parse(_, err) => Some(err),
156 }
157 }
158}
159
160impl<T> Json<T> {
161 /// Consumes the JSON wrapper and returns the wrapped item.
162 ///
163 /// # Example
164 /// ```rust
165 /// # use rocket::serde::json::Json;
166 /// let string = "Hello".to_string();
167 /// let my_json = Json(string);
168 /// assert_eq!(my_json.into_inner(), "Hello".to_string());
169 /// ```
170 #[inline(always)]
171 pub fn into_inner(self) -> T {
172 self.0
173 }
174}
175
176impl<'r, T: Deserialize<'r>> Json<T> {
177 fn from_str(s: &'r str) -> Result<Self, Error<'r>> {
178 serde_json::from_str(s).map(Json).map_err(|e| Error::Parse(s, e))
179 }
180
181 async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> Result<Self, Error<'r>> {
182 let limit = req.limits().get("json").unwrap_or(Limits::JSON);
183 let string = match data.open(limit).into_string().await {
184 Ok(s) if s.is_complete() => s.into_inner(),
185 Ok(_) => {
186 let eof = io::ErrorKind::UnexpectedEof;
187 return Err(Error::Io(io::Error::new(eof, "data limit exceeded")));
188 },
189 Err(e) => return Err(Error::Io(e)),
190 };
191
192 Self::from_str(local_cache!(req, string))
193 }
194}
195
196#[crate::async_trait]
197impl<'r, T: Deserialize<'r>> FromData<'r> for Json<T> {
198 type Error = Error<'r>;
199
200 async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> Outcome<'r, Self> {
201 match Self::from_data(req, data).await {
202 Ok(value) => Outcome::Success(value),
203 Err(Error::Io(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
204 Outcome::Error((Status::PayloadTooLarge, Error::Io(e)))
205 },
206 Err(Error::Parse(s, e)) if e.classify() == serde_json::error::Category::Data => {
207 Outcome::Error((Status::UnprocessableEntity, Error::Parse(s, e)))
208 },
209 Err(e) => Outcome::Error((Status::BadRequest, e)),
210
211 }
212 }
213}
214
215/// Serializes the wrapped value into JSON. Returns a response with Content-Type
216/// JSON and a fixed-size body with the serialized value. If serialization
217/// fails, an `Err` of `Status::InternalServerError` is returned.
218impl<'r, T: Serialize> Responder<'r, 'static> for Json<T> {
219 fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
220 let string = serde_json::to_string(&self.0)
221 .map_err(|e| {
222 error!("JSON serialize failure: {}", e);
223 Status::InternalServerError
224 })?;
225
226 content::RawJson(string).respond_to(req)
227 }
228}
229
230impl<T: Serialize> UriDisplay<Query> for Json<T> {
231 fn fmt(&self, f: &mut UriFormatter<'_, Query>) -> fmt::Result {
232 let string = to_string(&self.0).map_err(|_| fmt::Error)?;
233 f.write_value(&string)
234 }
235}
236
237macro_rules! impl_from_uri_param_from_inner_type {
238 ($($lt:lifetime)?, $T:ty) => (
239 impl<$($lt,)? T: Serialize> FromUriParam<Query, $T> for Json<T> {
240 type Target = Json<$T>;
241
242 #[inline(always)]
243 fn from_uri_param(param: $T) -> Self::Target {
244 Json(param)
245 }
246 }
247 )
248}
249
250impl_from_uri_param_from_inner_type!(, T);
251impl_from_uri_param_from_inner_type!('a, &'a T);
252impl_from_uri_param_from_inner_type!('a, &'a mut T);
253
254crate::http::impl_from_uri_param_identity!([Query] (T: Serialize) Json<T>);
255
256impl<T> From<T> for Json<T> {
257 fn from(value: T) -> Self {
258 Json(value)
259 }
260}
261
262impl<T> Deref for Json<T> {
263 type Target = T;
264
265 #[inline(always)]
266 fn deref(&self) -> &T {
267 &self.0
268 }
269}
270
271impl<T> DerefMut for Json<T> {
272 #[inline(always)]
273 fn deref_mut(&mut self) -> &mut T {
274 &mut self.0
275 }
276}
277
278impl From<Error<'_>> for form::Error<'_> {
279 fn from(e: Error<'_>) -> Self {
280 match e {
281 Error::Io(e) => e.into(),
282 Error::Parse(_, e) => form::Error::custom(e)
283 }
284 }
285}
286
287#[crate::async_trait]
288impl<'v, T: Deserialize<'v> + Send> form::FromFormField<'v> for Json<T> {
289 fn from_value(field: form::ValueField<'v>) -> Result<Self, form::Errors<'v>> {
290 Ok(Self::from_str(field.value)?)
291 }
292
293 async fn from_data(f: form::DataField<'v, '_>) -> Result<Self, form::Errors<'v>> {
294 Ok(Self::from_data(f.request, f.data).await?)
295 }
296}
297
298/// Serializes the value into JSON. Returns a response with Content-Type JSON
299/// and a fixed-size body with the serialized value.
300impl<'r> Responder<'r, 'static> for Value {
301 fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
302 content::RawJson(self.to_string()).respond_to(req)
303 }
304}
305
306crate::export! {
307 /// A macro to create ad-hoc JSON serializable values using JSON syntax.
308 ///
309 /// The return type of a `json!` invocation is [`Value`](Value). A value
310 /// created with this macro can be returned from a handler as follows:
311 ///
312 /// ```rust
313 /// # #[macro_use] extern crate rocket;
314 /// use rocket::serde::json::{json, Value};
315 ///
316 /// #[get("/json")]
317 /// fn get_json() -> Value {
318 /// json!({
319 /// "key": "value",
320 /// "array": [1, 2, 3, 4]
321 /// })
322 /// }
323 /// ```
324 ///
325 /// The [`Responder`](crate::response::Responder) implementation for
326 /// `Value` serializes the value into a JSON string and sets it as the body
327 /// of the response with a `Content-Type` of `application/json`.
328 ///
329 /// # Examples
330 ///
331 /// Create a simple JSON object with two keys: `"username"` and `"id"`:
332 ///
333 /// ```rust
334 /// use rocket::serde::json::json;
335 ///
336 /// let value = json!({
337 /// "username": "mjordan",
338 /// "id": 23
339 /// });
340 /// ```
341 ///
342 /// Create a more complex object with a nested object and array:
343 ///
344 /// ```rust
345 /// # use rocket::serde::json::json;
346 /// let value = json!({
347 /// "code": 200,
348 /// "success": true,
349 /// "payload": {
350 /// "features": ["serde", "json"],
351 /// "ids": [12, 121],
352 /// },
353 /// });
354 /// ```
355 ///
356 /// Variables or expressions can be interpolated into the JSON literal. Any type
357 /// interpolated into an array element or object value must implement serde's
358 /// `Serialize` trait, while any type interpolated into a object key must
359 /// implement `Into<String>`.
360 ///
361 /// ```rust
362 /// # use rocket::serde::json::json;
363 /// let code = 200;
364 /// let features = vec!["serde", "json"];
365 ///
366 /// let value = json!({
367 /// "code": code,
368 /// "success": code == 200,
369 /// "payload": {
370 /// features[0]: features[1]
371 /// }
372 /// });
373 /// ```
374 ///
375 /// Trailing commas are allowed inside both arrays and objects.
376 ///
377 /// ```rust
378 /// # use rocket::serde::json::json;
379 /// let value = json!([
380 /// "notice",
381 /// "the",
382 /// "trailing",
383 /// "comma -->",
384 /// ]);
385 /// ```
386 macro_rules! json {
387 ($($json:tt)+) => ($crate::serde::json::serde_json::json!($($json)*));
388 }
389}
390
391/// An arbitrary JSON value as returned by [`json!`].
392///
393/// # `Responder`
394///
395/// `Value` is a `Responder` that serializes the represented value into a JSON
396/// string and sets the string as the body of a fixed-sized response with a
397/// `Content-Type` of `application/json`.
398///
399/// # Usage
400///
401/// A value of this type is returned by [`json!`]. The macro and this type are
402/// typically used to construct JSON values in an ad-hoc fashion during request
403/// handling. This looks something like:
404///
405/// ```rust
406/// # #[macro_use] extern crate rocket;
407/// use rocket::serde::json::{json, Value};
408///
409/// #[get("/json")]
410/// fn get_json() -> Value {
411/// json!({
412/// "id": 83,
413/// "values": [1, 2, 3, 4]
414/// })
415/// }
416/// ```
417#[doc(inline)]
418pub use serde_json::Value;
419
420/// Deserialize an instance of type `T` from bytes of JSON text.
421///
422/// **_Always_ use [`Json`] to deserialize JSON request data.**
423///
424/// # Example
425///
426/// ```
427/// use rocket::serde::{Deserialize, json};
428///
429/// #[derive(Debug, PartialEq, Deserialize)]
430/// #[serde(crate = "rocket::serde")]
431/// struct Data<'r> {
432/// framework: &'r str,
433/// stars: usize,
434/// }
435///
436/// let bytes = br#"
437/// {
438/// "framework": "Rocket",
439/// "stars": 5
440/// }
441/// "#;
442///
443/// let data: Data = json::from_slice(bytes).unwrap();
444/// assert_eq!(data, Data { framework: "Rocket", stars: 5, });
445/// ```
446///
447/// # Errors
448///
449/// This conversion can fail if the structure of the input does not match the
450/// structure expected by `T`, for example if `T` is a struct type but the input
451/// contains something other than a JSON map. It can also fail if the structure
452/// is correct but `T`'s implementation of `Deserialize` decides that something
453/// is wrong with the data, for example required struct fields are missing from
454/// the JSON map or some number is too big to fit in the expected primitive
455/// type.
456#[inline(always)]
457pub fn from_slice<'a, T>(slice: &'a [u8]) -> Result<T, serde_json::error::Error>
458 where T: Deserialize<'a>,
459{
460 serde_json::from_slice(slice)
461}
462
463/// Deserialize an instance of type `T` from a string of JSON text.
464///
465/// **_Always_ use [`Json`] to deserialize JSON request data.**
466///
467/// # Example
468///
469/// ```
470/// use rocket::serde::{Deserialize, json};
471///
472/// #[derive(Debug, PartialEq, Deserialize)]
473/// #[serde(crate = "rocket::serde")]
474/// struct Data<'r> {
475/// framework: &'r str,
476/// stars: usize,
477/// }
478///
479/// let string = r#"
480/// {
481/// "framework": "Rocket",
482/// "stars": 5
483/// }
484/// "#;
485///
486/// let data: Data = json::from_str(string).unwrap();
487/// assert_eq!(data, Data { framework: "Rocket", stars: 5, });
488/// ```
489///
490/// # Errors
491///
492/// This conversion can fail if the structure of the input does not match the
493/// structure expected by `T`, for example if `T` is a struct type but the input
494/// contains something other than a JSON map. It can also fail if the structure
495/// is correct but `T`'s implementation of `Deserialize` decides that something
496/// is wrong with the data, for example required struct fields are missing from
497/// the JSON map or some number is too big to fit in the expected primitive
498/// type.
499#[inline(always)]
500pub fn from_str<'a, T>(string: &'a str) -> Result<T, serde_json::error::Error>
501 where T: Deserialize<'a>,
502{
503 serde_json::from_str(string)
504}
505
506/// Serialize a `T` into a JSON string with compact representation.
507///
508/// **_Always_ use [`Json`] to serialize JSON response data.**
509///
510/// # Example
511///
512/// ```
513/// use rocket::serde::{Deserialize, Serialize, json};
514///
515/// #[derive(Debug, PartialEq, Deserialize, Serialize)]
516/// #[serde(crate = "rocket::serde")]
517/// struct Data<'r> {
518/// framework: &'r str,
519/// stars: usize,
520/// }
521///
522/// let data = Data {
523/// framework: "Rocket",
524/// stars: 5,
525/// };
526///
527/// let string = json::to_string(&data).unwrap();
528/// let data: Data = json::from_str(&string).unwrap();
529/// assert_eq!(data, Data { framework: "Rocket", stars: 5, });
530/// ```
531///
532/// # Errors
533///
534/// Serialization fails if `T`'s `Serialize` implementation fails or if `T`
535/// contains a map with non-string keys.
536#[inline(always)]
537pub fn to_string<T>(value: &T) -> Result<String, serde_json::error::Error>
538 where T: Serialize
539{
540 serde_json::to_string(value)
541}
542
543/// Serialize a `T` into a JSON string with "pretty" formatted representation.
544///
545/// **_Always_ use [`Json`] to serialize JSON response data.**
546///
547/// # Example
548///
549/// ```
550/// use rocket::serde::{Deserialize, Serialize, json};
551///
552/// #[derive(Debug, PartialEq, Deserialize, Serialize)]
553/// #[serde(crate = "rocket::serde")]
554/// struct Data<'r> {
555/// framework: &'r str,
556/// stars: usize,
557/// }
558///
559/// let data = Data {
560/// framework: "Rocket",
561/// stars: 5,
562/// };
563///
564/// let string = json::to_pretty_string(&data).unwrap();
565/// # let compact = json::to_string(&data).unwrap();
566/// # assert_ne!(compact, string);
567/// let data: Data = json::from_str(&string).unwrap();
568/// assert_eq!(data, Data { framework: "Rocket", stars: 5, });
569/// ```
570///
571/// # Errors
572///
573/// Serialization fails if `T`'s `Serialize` implementation fails or if `T`
574/// contains a map with non-string keys.
575#[inline(always)]
576pub fn to_pretty_string<T>(value: &T) -> Result<String, serde_json::error::Error>
577 where T: Serialize
578{
579 serde_json::to_string_pretty(value)
580}
581
582/// Interpret a [`Value`] as an instance of type `T`.
583///
584/// # Example
585///
586/// ```
587/// use rocket::serde::{Deserialize, json};
588///
589/// #[derive(Debug, PartialEq, Deserialize)]
590/// #[serde(crate = "rocket::serde")]
591/// struct Data {
592/// framework: String ,
593/// stars: usize,
594/// }
595///
596/// let value = json::json!({
597/// "framework": "Rocket",
598/// "stars": 5
599/// });
600///
601/// let data: Data = json::from_value(value).unwrap();
602/// assert_eq!(data, Data { framework: "Rocket".into(), stars: 5, });
603/// ```
604///
605/// # Errors
606///
607/// This conversion can fail if the structure of the input does not match the
608/// structure expected by `T`, for example if `T` is a struct type but the input
609/// contains something other than a JSON map. It can also fail if the structure
610/// is correct but `T`'s implementation of `Deserialize` decides that something
611/// is wrong with the data, for example required struct fields are missing from
612/// the JSON map or some number is too big to fit in the expected primitive
613/// type.
614#[inline(always)]
615pub fn from_value<T>(value: Value) -> Result<T, serde_json::error::Error>
616 where T: crate::serde::DeserializeOwned
617{
618 serde_json::from_value(value)
619}
620
621/// Convert a `T` into a [`Value`], an opaque value representing JSON data.
622///
623/// # Example
624///
625/// ```
626/// use rocket::serde::{Deserialize, Serialize, json};
627///
628/// #[derive(Deserialize, Serialize)]
629/// #[serde(crate = "rocket::serde")]
630/// struct Data {
631/// framework: String ,
632/// stars: usize,
633/// }
634///
635/// let value = json::json!({
636/// "framework": "Rocket",
637/// "stars": 5
638/// });
639///
640/// let data: Data = json::from_value(value.clone()).unwrap();
641/// let data_value = json::to_value(data).unwrap();
642/// assert_eq!(value, data_value);
643/// ```
644///
645/// # Errors
646///
647/// This conversion fails if `T`’s implementation of `Serialize` decides to fail
648/// or if `T` contains a map with non-string keys.
649#[inline(always)]
650pub fn to_value<T>(item: T) -> Result<Value, serde_json::error::Error>
651 where T: Serialize
652{
653 serde_json::to_value(item)
654}