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

Safe HaskellNone
LanguageHaskell98

Yesod.Core.Json

Contents

Synopsis

Convert from a JSON value

defaultLayoutJson Source #

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 Value Source #

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 Value Source #

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

Since: 1.2.1

returnJsonEncoding :: (Monad m, ToJSON a) => a -> m Encoding Source #

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

Since: 1.4.21

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

Provide a JSON representation for usage with selectReps, using aeson's toJSON (aeson >= 0.11: toEncoding) 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 a Source #

Deprecated: Use requireJsonBody instead

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

requireJsonBody :: (MonadHandler m, FromJSON a) => m a Source #

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.

Instances

Eq Value 

Methods

(==) :: Value -> Value -> Bool #

(/=) :: Value -> Value -> Bool #

Data Value 

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Value -> c Value #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Value #

toConstr :: Value -> Constr #

dataTypeOf :: Value -> DataType #

dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c Value) #

dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value) #

gmapT :: (forall b. Data b => b -> b) -> Value -> Value #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r #

gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r #

gmapQ :: (forall d. Data d => d -> u) -> Value -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Value -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Value -> m Value #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Value -> m Value #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Value -> m Value #

Read Value 
Show Value 

Methods

showsPrec :: Int -> Value -> ShowS #

show :: Value -> String #

showList :: [Value] -> ShowS #

IsString Value 

Methods

fromString :: String -> Value #

Lift Value 

Methods

lift :: Value -> Q Exp #

NFData Value 

Methods

rnf :: Value -> () #

Hashable Value 

Methods

hashWithSalt :: Int -> Value -> Int #

hash :: Value -> Int #

ToJavascript Value 
ToTypedContent Value Source # 
HasContentType Value Source # 
ToContent Value Source # 

class ToJSON a where #

A type that can be converted to JSON.

An example type and instance:

-- Allow ourselves to write Text literals.
{-# LANGUAGE OverloadedStrings #-}

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

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

  toEncoding (Coord x y) = pairs ("x" .= x <> "y" .= y)

Instead of manually writing your ToJSON instance, there are two 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:
  • The compiler can provide a default generic implementation for toJSON.

To use the second, simply add a deriving Generic clause to your datatype and declare a ToJSON instance for your datatype without giving definitions for toJSON or toEncoding.

For example, the previous example can be simplified to a more minimal instance:

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics

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

instance ToJSON Coord where
    toEncoding = genericToEncoding defaultOptions

Why do we provide an implementation for toEncoding here? The toEncoding function is a relatively new addition to this class. To allow users of older versions of this library to upgrade without having to edit all of their instances or encounter surprising incompatibilities, the default implementation of toEncoding uses toJSON. This produces correct results, but since it performs an intermediate conversion to a Value, it will be less efficient than directly emitting an Encoding. Our one-liner definition of toEncoding above bypasses the intermediate Value.

If DefaultSignatures doesn't give exactly the results you want, you can customize the generic encoding with only a tiny amount of effort, using genericToJSON and genericToEncoding with your preferred Options:

instance ToJSON Coord where
    toJSON     = genericToJSON defaultOptions
    toEncoding = genericToEncoding defaultOptions

Minimal complete definition

Nothing

class FromJSON a where #

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

In many cases, you can get the compiler to generate parsing code for you (see below). To begin, let's cover writing an instance by hand.

There are various reasons a conversion could fail. For example, an Object could be missing a required key, an Array could be of the wrong size, or a value could be of an incompatible type.

The basic ways to signal a failed conversion are as follows:

  • empty and mzero work, but are terse and uninformative
  • fail yields a custom error message
  • typeMismatch produces an informative message for cases when the value encountered is not of the expected type

An example type and instance:

-- Allow ourselves to write Text literals.
{-# LANGUAGE OverloadedStrings #-}

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

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

  -- We do not expect a non-Object value here.
  -- We could use mzero to fail, but typeMismatch
  -- gives a much more informative error message.
  parseJSON invalid    = typeMismatch "Coord" invalid

Instead of manually writing your FromJSON instance, there are two 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:
  • The compiler can provide a default generic implementation for parseJSON.

To use the second, 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

If DefaultSignatures doesn't give exactly the results you want, you can customize the generic decoding with only a tiny amount of effort, using genericParseJSON with your preferred Options:

instance FromJSON Coord where
    parseJSON = genericParseJSON defaultOptions

Minimal complete definition

Nothing

array :: ToJSON a => [a] -> Value Source #

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.

(.=) :: KeyValue kv => forall v. ToJSON v => Text -> v -> kv #

(.:) :: 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

jsonOrRedirect Source #

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.

jsonEncodingOrRedirect Source #

Arguments

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

Redirect target

-> a

Data to send via JSON

-> m Encoding 

jsonEncodingOrRedirect 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. @since 1.4.21

acceptsJson :: MonadHandler m => m Bool Source #

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