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:
fail yields a custom error message: it is the recommended way of
reporting a failure;
empty (or mzero) is uninformative:
use it when the error is meant to be caught by some (<|>);
typeMismatch can be used to report a failure when the encountered value
is not of the expected JSON type; unexpected is an appropriate alternative
when more than one type may be expected, or to keep the expected type
implicit.
-- 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 empty to fail, but typeMismatch
-- gives a much more informative error message.
parseJSON invalid =
prependFailure "parsing Coord failed, "
(typeMismatch "Object" invalid)
For this common case of only being concerned with a single
type of JSON value, the functions withObject, withScientific, etc.
are provided. Their use is to be preferred when possible, since
they are more terse. Using withObject, we can rewrite the above instance
(assuming the same language extension and data type) as:
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 it will probably be more efficient than the following option.
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
The default implementation will be equivalent to
parseJSON = genericParseJSONdefaultOptions; if you need different
options, you can customize the generic decoding by defining:
FromJSONValueDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONIntSetDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONIntegerDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
This instance includes a bounds check to prevent maliciously
large inputs to fill up the memory of the target system. You can
newtype Scientific and provide your own instance using
withScientific if you want to allow larger inputs.
FromJSONNaturalDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONVoidDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONAllDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONAnyDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONVersionDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONCTimeDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONInt16Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONInt32Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONInt64Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONInt8Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONWord16Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONWord32Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONWord64Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONWord8Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONBoolDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONCharDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONDoubleDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONFloatDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONIntDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONOrderingDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONWordDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONURIDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONDayOfWeekDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSONDiffTimeDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
This instance includes a bounds check to prevent maliciously
large inputs to fill up the memory of the target system. You can
newtype Scientific and provide your own instance using
withScientific if you want to allow larger inputs.
This instance includes a bounds check to prevent maliciously
large inputs to fill up the memory of the target system. You can
newtype Scientific and provide your own instance using
withScientific if you want to allow larger inputs.
The first space may instead be a T, and the second space is
optional. The Z represents UTC. The Z may be replaced with a
time zone offset of the form +0000 or -08:00, where the first
two digits are hours, the : is optional and the second two digits
(also optional) are minutes.
FromJSONUUIDDefined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
FromJSON ()Defined in aeson-2.2.3.0 · Data.Aeson.Types.FromJSON
This instance includes a bounds check to prevent maliciously
large inputs to fill up the memory of the target system. You can
newtype Scientific and provide your own instance using
withScientific if you want to allow larger inputs.
Instances in general must specify toJSON and should (but don't need
to) specify toEncoding.
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 it will probably be more efficient than the following option.
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. If you require nothing other than
defaultOptions, it is sufficient to write (and this is the only
alternative where the default toJSON implementation is sufficient):
Previous versions of this library only had the toJSON method. Adding
toEncoding had two reasons:
toEncoding is more efficient for the common case that the output of
toJSON is directly serialized to a ByteString.
Further, expressing either method in terms of the other would be
non-optimal.
The choice of defaults allows a smooth transition for existing users:
Existing instances that do not define toEncoding still
compile and have the correct semantics. This is ensured by making
the default implementation of toEncoding use 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.
(this also means that specifying nothing more than
instance ToJSON Coord would be sufficient as a generically decoding
instance, but there probably exists no good reason to not specify
toEncoding in new instances.)
Instances114ToJSON, …
ToJSONKeyDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONDotNetTimeDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONValueDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONIntSetDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONIntegerDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONNaturalDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONVoidDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONAllDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONAnyDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONVersionDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONCTimeDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONInt16Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONInt32Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONInt64Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONInt8Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONWord16Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONWord32Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONWord64Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONWord8Defined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONBoolDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONCharDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONDoubleDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONFloatDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONIntDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONOrderingDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONWordDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONURIDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONScientificDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONTextDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONTextDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON
ToJSONShortTextDefined in aeson-2.2.3.0 · Data.Aeson.Types.ToJSON