How to use this library

This section contains basic information on the different ways to
work with data using this library. These range from simple but
inflexible, to complex but flexible.

The most common way to use the library is to define a data type,
corresponding to some JSON data you want to work with, and then
write either a FromJSON instance, a to ToJSON instance, or both
for that type.

Writing instances by hand

When necessary, we can write ToJSON and FromJSON instances by
hand. This is valuable when the JSON-on-the-wire and Haskell data
are different or otherwise need some more carefully managed
translation. Let's revisit our JSON data:

{ "name": "Joe", "age": 12 }

We once again create a matching data type, without bothering to add
a Generic instance this time:

Working with the AST

Sometimes you want to work with JSON data directly, without first
converting it to a custom data type. This can be useful if you want
to e.g. convert JSON data to YAML data, without knowing what the
contents of the original JSON data was. The Value type, which is
an instance of FromJSON, is used to represent an arbitrary JSON
AST (abstract syntax tree). Example usage:

Considering that any type that implements FromJSON can be used
here, this is quite a powerful way to parse JSON. See the
documentation in FromJSON for how to implement this class for
your own data types.

The downside is that you have to write the parser yourself; the
upside is that you have complete control over the way the JSON is
parsed.

Encoding and decoding

Decoding is a two-step process.

When decoding a value, the process is reversed: the bytes are
converted to a Value, then the FromJSON class is used to
convert to the desired type.

There are two ways to encode a value.

Convert to a Value using toJSON, then possibly further
encode. This was the only method available in aeson 0.9 and
earlier.

Directly encode (to what will become a ByteString) using
toEncoding. This is much more efficient (about 3x faster, and
less memory intensive besides), but is only available in aeson
0.10 and newer.

Direct encoding

In older versions of this library, encoding a Haskell value
involved converting to an intermediate Value, then encoding that.

A "direct" encoder converts straight from a source Haskell value
to a ByteString without constructing an intermediate Value.
This approach is faster than toJSON, and allocates less memory.
The toEncoding method makes it possible to implement direct
encoding with low memory overhead.

To complicate matters, the default implementation of toEncoding
uses toJSON. Why? The toEncoding method was added to this
library much more recently than toJSON. Using toJSON ensures
that packages written against older versions of this library will
compile and produce correct output, but they will not see any
speedup from direct encoding.

To write a minimal implementation of direct encoding, your type
must implement GHC's Generic class, and your code should look
like this:

For this common case of only being concerned with a single
type of JSON value, the functions withObject, withNumber, 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.

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.

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.

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.

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 to 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.)

The default implementation of this method creates an
intermediate Value using toJSON. This provides
source-level compatibility for people upgrading from older
versions of this library, but obviously offers no performance
advantage.

To benefit from direct encoding, you must provide an
implementation for this method. The easiest way to do so is by
having your types implement Generic using the DeriveGeneric
extension, and then have GHC generate a method body as follows.

Keys for maps

Typeclass for types that can be used as the key of a map-like container
(like Map or HashMap). For example, since Text has a ToJSONKey
instance and Char has a ToJSON instance, we can encode a value of
type MapTextChar:

JSON documents only accept strings as object keys. For any type
from base that has a natural textual representation, it can be
expected that its ToJSONKey instance will choose that representation.

For data types that lack a natural textual representation, an alternative
is provided. The map-like container is represented as a JSON array
instead of a JSON object. Each value in the array is an array with
exactly two values. The first is the key and the second is the value.

For example, values of type '[Text]' cannot be encoded to a
string, so a Map with keys of type '[Text]' is encoded as follows:

The default implementation of ToJSONKey chooses this method of
encoding a key, using the ToJSON instance of the type.

To use your own data type as the key in a map, all that is needed
is to write a ToJSONKey (and possibly a FromJSONKey) instance
for it. If the type cannot be trivially converted to and from Text,
it is recommended that ToJSONKeyValue is used. Since the default
implementations of the typeclass methods can build this from a
ToJSON instance, there is nothing that needs to be written:

It is possible to get the ToJSONKey instance for free as we did
with Foo. However, in this case, we have a natural way to go to
and from Text that does not require any escape sequences. So, in
this example, ToJSONKeyText will be used instead of ToJSONKeyValue.
The Show instance can be used to help write ToJSONKey:

The performance of the above instance can be improved by
not using String as an intermediate step when converting to
Text. One option for improving performance would be to use
template haskell machinery from the text-show package. However,
even with the approach, the Encoding (a wrapper around a bytestring
builder) is generated by encoding the Text to a ByteString,
an intermediate step that could be avoided. The fastest possible
implementation would be:

This works because GHC can lift the encoded values out of the case
statements, which means that they are only evaluated once. This
approach should only be used when there is a serious need to
maximize performance.

This is similar in spirit to the showsList method of Show.
It makes it possible to give String keys special treatment
without using OverlappingInstances. End users should always
be able to use the default implementation of this method.

This is similar in spirit to the showsList method of Show.
It makes it possible to give String keys special treatment
without using OverlappingInstances. End users should always
be able to use the default implementation of this method.

Read the docs for ToJSONKey first. This class is a conversion
in the opposite direction. If you have a newtype wrapper around Text,
the recommended way to define instances is with generalized newtype deriving:

This is similar in spirit to the readList method of Read.
It makes it possible to give String keys special treatment
without using OverlappingInstances. End users should always
be able to use the default implementation of this method.

This is similar in spirit to the readList method of Read.
It makes it possible to give String keys special treatment
without using OverlappingInstances. End users should always
be able to use the default implementation of this method.

This type is related to ToJSONKeyFunction. If FromJSONKeyValue is used in the
FromJSONKey instance, then ToJSONKeyValue should be used in the ToJSONKey
instance. The other three data constructors for this type all correspond to
ToJSONKeyText. Strictly speaking, FromJSONKeyTextParser is more powerful than
FromJSONKeyText, which is in turn more powerful than FromJSONKeyCoerce.
For performance reasons, these exist as three options instead of one.

Liftings to unary and binary type constructors

Instead of manually writing your FromJSON1 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
liftParseJSON.

To use the second, simply add a deriving Generic1 clause to your
datatype and declare a FromJSON1 instance for your datatype without giving
a definition for liftParseJSON.

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

Instead of manually writing your ToJSON1 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
toJSON1.

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

Constructors and accessors

A series of values that, when encoded, should be separated by
commas. Since 0.11.0.0, the .= operator is overloaded to create
either (Text, Value) or Series. You can use Series when
encoding directly to a bytestring builder as in the following
example:

Helper for use in combination with .:? to provide default
values for optional JSON object fields.

This combinator is most useful if the key and value can be absent
from an object without affecting its validity and we know a default
value to assign in that case. If the key and value are mandatory,
use .: instead.

Parsing

The conversion of a parsed value to a Haskell value is deferred
until the Haskell value is needed. This may improve performance if
only a subset of the results of conversions are needed, but at a
cost in thunk allocation.

This function is an alias for value. In aeson 0.8 and earlier, it
parsed only object or array types, in conformance with the
now-obsolete RFC 4627.