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}