yesod-core-1.2.20: Creation of type-safe, RESTful web applications.

Safe HaskellNone

Yesod.Core.Json

Contents

Synopsis

Convert from a JSON value

defaultLayoutJsonSource

Arguments

:: (Yesod site, ToJSON a) 
=> WidgetT site IO ()

HTML

-> HandlerT site IO a

JSON

-> HandlerT site IO TypedContent 

Provide both an HTML and JSON representation for a piece of data, using the default layout for the HTML output (defaultLayout).

Since: 0.3.0

jsonToRepJson :: (Monad m, ToJSON a) => a -> m ValueSource

Deprecated: Use returnJson instead

Wraps a data type in a RepJson. The data type must support conversion to JSON via ToJSON.

Since: 0.3.0

returnJson :: (Monad m, ToJSON a) => a -> m ValueSource

Convert a value to a JSON representation via aeson's toJSON function.

Since 1.2.1

provideJson :: (Monad m, ToJSON a) => a -> Writer (Endo [ProvidedRep m]) ()Source

Provide a JSON representation for usage with selectReps, using aeson's toJSON function to perform the conversion.

Since 1.2.1

Convert to a JSON value

parseJsonBody :: (MonadHandler m, FromJSON a) => m (Result a)Source

Parse the request body to a data type as a JSON value. The data type must support conversion from JSON via FromJSON. If you want the raw JSON value, just ask for a Result Value.

Note that this function will consume the request body. As such, calling it twice will result in a parse error on the second call, since the request body will no longer be available.

Since: 0.3.0

parseJsonBody_ :: (MonadHandler m, FromJSON a) => m aSource

Deprecated: Use requireJsonBody instead

Same as parseJsonBody, but return an invalid args response on a parse error.

requireJsonBody :: (MonadHandler m, FromJSON a) => m aSource

Same as parseJsonBody, but return an invalid args response on a parse error.

Produce JSON values

data Value

A JSON value represented as a Haskell value.

Constructors

Object !Object 
Array !Array 
String !Text 
Number !Scientific 
Bool !Bool 
Null 

class ToJSON a where

A type that can be converted to JSON.

An example type and instance:

{-# LANGUAGE OverloadedStrings #-}

data Coord = Coord { x :: Double, y :: Double }

instance ToJSON Coord where
   toJSON (Coord x y) = object ["x" .= x, "y" .= y]

Note the use of the OverloadedStrings language extension which enables Text values to be written as string literals.

Instead of manually writing your ToJSON instance, there are three options to do it automatically:

  • Data.Aeson.TH provides template-haskell functions which will derive an instance at compile-time. The generated instance is optimized for your type so will probably be more efficient than the following two options:
  • Data.Aeson.Generic provides a generic toJSON function that accepts any type which is an instance of Data.
  • If your compiler has support for the DeriveGeneric and DefaultSignatures language extensions (GHC 7.2 and newer), toJSON will have a default generic implementation.

To use the latter option, simply add a deriving Generic clause to your datatype and declare a ToJSON instance for your datatype without giving a definition for toJSON.

For example the previous example can be simplified to just:

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics

data Coord = Coord { x :: Double, y :: Double } deriving Generic

instance ToJSON Coord

Note that, instead of using DefaultSignatures, it's also possible to parameterize the generic encoding using genericToJSON applied to your encoding/decoding Options:

 instance ToJSON Coord where
     toJSON = genericToJSON defaultOptions

Methods

toJSON :: a -> Value

Instances

ToJSON Bool 
ToJSON Char 
ToJSON Double 
ToJSON Float 
ToJSON Int 
ToJSON Int8 
ToJSON Int16 
ToJSON Int32 
ToJSON Int64 
ToJSON Integer 
ToJSON Word 
ToJSON Word8 
ToJSON Word16 
ToJSON Word32 
ToJSON Word64 
ToJSON () 
ToJSON Scientific 
ToJSON Number 
ToJSON Text 
ToJSON UTCTime 
ToJSON Value 
ToJSON DotNetTime 
ToJSON Text 
ToJSON IntSet 
ToJSON ZonedTime 
ToJSON [Char] 
ToJSON a => ToJSON [a] 
ToJSON (Ratio Integer) 
ToJSON a => ToJSON (Maybe a) 
ToJSON a => ToJSON (Dual a) 
ToJSON a => ToJSON (First a) 
ToJSON a => ToJSON (Last a) 
ToJSON a => ToJSON (HashSet a) 
ToJSON a => ToJSON (Vector a) 
(Vector Vector a, ToJSON a) => ToJSON (Vector a) 
(Storable a, ToJSON a) => ToJSON (Vector a) 
(Prim a, ToJSON a) => ToJSON (Vector a) 
ToJSON v => ToJSON (Tree v) 
ToJSON a => ToJSON (Set a) 
ToJSON a => ToJSON (IntMap a) 
HasResolution a => ToJSON (Fixed a) 
(ToJSON a, ToJSON b) => ToJSON (Either a b) 
(ToJSON a, ToJSON b) => ToJSON (a, b) 
ToJSON v => ToJSON (HashMap String v) 
ToJSON v => ToJSON (HashMap Text v) 
ToJSON v => ToJSON (HashMap Text v) 
ToJSON v => ToJSON (Map String v) 
ToJSON v => ToJSON (Map Text v) 
ToJSON v => ToJSON (Map Text v) 
(ToJSON a, ToJSON b, ToJSON c) => ToJSON (a, b, c) 
(ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON (a, b, c, d) 
(ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON (a, b, c, d, e) 
(ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON (a, b, c, d, e, f) 
(ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON (a, b, c, d, e, f, g) 

class FromJSON a where

A type that can be converted from JSON, with the possibility of failure.

When writing an instance, use empty, mzero, or fail to make a conversion fail, e.g. if an Object is missing a required key, or the value is of the wrong type.

An example type and instance:

{-# LANGUAGE OverloadedStrings #-}

data Coord = Coord { x :: Double, y :: Double }

instance FromJSON Coord where
   parseJSON (Object v) = Coord    <$>
                          v .: "x" <*>
                          v .: "y"

-- A non-Object value is of the wrong type, so use mzero to fail.
   parseJSON _          = mzero

Note the use of the OverloadedStrings language extension which enables Text values to be written as string literals.

Instead of manually writing your FromJSON instance, there are three options to do it automatically:

  • Data.Aeson.TH provides template-haskell functions which will derive an instance at compile-time. The generated instance is optimized for your type so will probably be more efficient than the following two options:
  • Data.Aeson.Generic provides a generic fromJSON function that parses to any type which is an instance of Data.
  • If your compiler has support for the DeriveGeneric and DefaultSignatures language extensions, parseJSON will have a default generic implementation.

To use this, simply add a deriving Generic clause to your datatype and declare a FromJSON instance for your datatype without giving a definition for parseJSON.

For example the previous example can be simplified to just:

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics

data Coord = Coord { x :: Double, y :: Double } deriving Generic

instance FromJSON Coord

Note that, instead of using DefaultSignatures, it's also possible to parameterize the generic decoding using genericParseJSON applied to your encoding/decoding Options:

 instance FromJSON Coord where
     parseJSON = genericParseJSON defaultOptions

Methods

parseJSON :: Value -> Parser a

Instances

FromJSON Bool 
FromJSON Char 
FromJSON Double 
FromJSON Float 
FromJSON Int 
FromJSON Int8 
FromJSON Int16 
FromJSON Int32 
FromJSON Int64 
FromJSON Integer

WARNING: Only parse Integers from trusted input since an attacker could easily fill up the memory of the target system by specifying a scientific number with a big exponent like 1e1000000000.

FromJSON Word 
FromJSON Word8 
FromJSON Word16 
FromJSON Word32 
FromJSON Word64 
FromJSON () 
FromJSON Scientific 
FromJSON Number 
FromJSON Text 
FromJSON UTCTime 
FromJSON Value 
FromJSON DotNetTime 
FromJSON Text 
FromJSON IntSet 
FromJSON ZonedTime 
FromJSON [Char] 
FromJSON a => FromJSON [a] 
FromJSON (Ratio Integer) 
FromJSON a => FromJSON (Maybe a) 
FromJSON a => FromJSON (Dual a) 
FromJSON a => FromJSON (First a) 
FromJSON a => FromJSON (Last a) 
(Eq a, Hashable a, FromJSON a) => FromJSON (HashSet a) 
FromJSON a => FromJSON (Vector a) 
(Vector Vector a, FromJSON a) => FromJSON (Vector a) 
(Storable a, FromJSON a) => FromJSON (Vector a) 
(Prim a, FromJSON a) => FromJSON (Vector a) 
FromJSON v => FromJSON (Tree v) 
(Ord a, FromJSON a) => FromJSON (Set a) 
FromJSON a => FromJSON (IntMap a) 
HasResolution a => FromJSON (Fixed a)

WARNING: Only parse fixed-precision numbers from trusted input since an attacker could easily fill up the memory of the target system by specifying a scientific number with a big exponent like 1e1000000000.

(FromJSON a, FromJSON b) => FromJSON (Either a b) 
(FromJSON a, FromJSON b) => FromJSON (a, b) 
FromJSON v => FromJSON (HashMap String v) 
FromJSON v => FromJSON (HashMap Text v) 
FromJSON v => FromJSON (HashMap Text v) 
FromJSON v => FromJSON (Map String v) 
FromJSON v => FromJSON (Map Text v) 
FromJSON v => FromJSON (Map Text v) 
(FromJSON a, FromJSON b, FromJSON c) => FromJSON (a, b, c) 
(FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON (a, b, c, d) 
(FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON (a, b, c, d, e) 
(FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON (a, b, c, d, e, f) 
(FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON (a, b, c, d, e, f, g) 

array :: ToJSON a => [a] -> ValueSource

Convert a list of values to an Array.

object :: [Pair] -> Value

Create a Value from a list of name/value Pairs. If duplicate keys arise, earlier keys and their associated values win.

(.=) :: ToJSON a => Text -> a -> Pair

Construct a Pair from a key and a value.

(.:) :: FromJSON a => Object -> Text -> Parser a

Retrieve the value associated with the given key of an Object. The result is empty if the key is not present or the value cannot be converted to the desired type.

This accessor is appropriate if the key and value must be present in an object for it to be valid. If the key and value are optional, use '(.:?)' instead.

Convenience functions

jsonOrRedirectSource

Arguments

:: (MonadHandler m, ToJSON a) 
=> Route (HandlerSite m)

Redirect target

-> a

Data to send via JSON

-> m Value 

jsonOrRedirect simplifies the scenario where a POST handler sends a different response based on Accept headers:

  1. 200 with JSON data if the client prefers application/json (e.g. AJAX, see acceptsJSON).
  2. 3xx otherwise, following the PRG pattern.

acceptsJson :: MonadHandler m => m BoolSource

Returns True if the client prefers application/json as indicated by the Accept HTTP header.