Fault tolerant JSON parsing

aeson, haskell, json

Solution

If you are using GHC 7.2 or 7.4, the new generics support in `aeson` doesn't check for extra fields. I'm not sure if this is by design or not but we use it for the same reason.

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import qualified Data.Aeson.Types
import Data.Attoparsec
import qualified Data.ByteString as BS
import Data.ByteString.Char8 ()
import GHC.Generics

data MyRecord = MyRecord
  { field1 :: Int
  } deriving (Generic, Show)

instance FromJSON MyRecord

myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord
myRecordFromJSONString s = case Data.Attoparsec.parse json s of
  Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res
  _              -> Nothing

main :: IO ()
main = do
  let parsed = myRecordFromJSONString "{ \"field1\": 1, \"field2\": 2 }"
  print parsed

Running this would fail with the TH derived instance due to 'field2' not existing in the record. The `Generic` instance returns the desired result:

Just (MyRecord {field1 = 1})

Problem

I'm using Data.Aeson to parse some JSON into a Record type. From time to time data is added to the JSON and this breaks my code as Aeson complains something to the effect of: expected Object with 21 name/value pairs but got 23 name/value I'd really prefer to parse the JSON in a fault tolerant way -- I don't care if more fields are added to the JSON at a later date, just parse whatever you can! Is there a way to achieve this fault tolerance? Here's my code: ``` myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord myRecordFromJSONString s = case Data.Attoparsec.parse json s of Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res _ -> Nothing ``` I should add that I'm using deriveJSON from Data.Aeson.TH to generate the parsing code. If I write the FromJSON code manually it's fault tolerant but I'd like to not have to do that...

Original source