Struggles with parsing JSON with Aeson

Aeson is the de-facto library to get data to and from json. It works very well but there is a lot of magic and I had some issue tweaking the default behaviors, notably to add some more error messages.

Simple usecases

Let's start with an very simple example, to show the strength and ease of use for normal usecases.

Now, given a simple json file:

The parsing is straightforward:

When things go wrong

With eitherDecode, it's always possible to get some error message. For example:

Will yield Left "Error in $: expected person, encountered Array". A missing key also will raise an error: {"id": "1"} yields Left "Error in $: key \"name\" not present".

Extending the error messages

Now, I had to import a fairly big array of json, and one of the record was invalid. The overall error was just about an invalid key type, but I had no idea where the error was. So the next task is to have more verbose logging in case things go wrong (and they will do, always).

For a single object

What we want is an improved parser of type Value -> Parser (Either String Person) where the error message will be more verbose.

And then, we can use this parser:

Running this example with {"id": "1"} will gives:

For an array of objects

Now, we want to use this verbose parser for an array of objects. We can't rely on the default FromJSON instances for an array, so we have to manually specify and run the parser:

Bonus: with nested structure

Let's assume the json is not a plain array, but something like:

We wrap the previous parser with another one:

And then, this new parser can be used wherever the previous one was used.

Conclusion

Aeson has a lot of nice default, but understanding all the magic to extend the default behaviors can be hard at first. I believe this set of examples is enough to tackle a lot of usecase. Another great resource to understand Aeson magic is this other aeson tutorial. The official aeson doc is great too.