ToJSON is the aeson type class for turning Haskell values into JSON. A value with a ToJSON instance can be converted to an aeson Value with toJSON, then written as a lazy ByteString with encode. Built-in instances handle values such as strings, numbers, Booleans, lists, and values nested inside other serializable types. section 16.1.1 section 16.1.2
For a record such as a todo entry, define toJSON by constructing an object. Each JSON field is made with .=, which pairs a key with a value that itself has a ToJSON instance. Optional Maybe fields can therefore be included alongside text, Boolean, and numeric fields. section 16.1.2
Listing 16.3 A ToJSON instance for TodoEntry
todoEntrySerializer :: TodoEntry -> J.Value
todoEntrySerializer TodoEntry {..} = do
J.object #1
[ "entryId" J..= entryId, #2
"text" J..= text, #2
"checked" J..= checked, #2
"rank" J..= rank #2
]
instance J.ToJSON TodoEntry where
toJSON = todoEntrySerializer #3
A complete TodoEntry serializer maps every record field to a JSON key, then installs it as the ToJSON instance. section 16.1.2
Manual instances make the JSON shape explicit, but repeating every field in both serialization and parsing can become boilerplate. For record types, deriving Generic lets aeson supply default ToJSON and FromJSON implementations: derive Generic, then declare the instances with no method bodies. section 16.2
Generic aeson encoding follows these useful rules:
- Named record fields become key-value pairs in a JSON object. section 16.2
- Multiple constructors use a tag containing the constructor name; constructors with unlabeled fields become a field or an array. section 16.2
- Maybe values become optional JSON values and serialize as null when absent; serializable nested types are encoded recursively. section 16.2
Check a JSON round trip
Given `e = TodoEntry Nothing "Do Something" False (Just 1)`, `encode e` produces a JSON object with `entryId: null`, `rank: 1`, and the other fields. Decoding that output as `Maybe TodoEntry` returns the original value, checking that the serializer and parser agree. section 16.1.2 section 16.2
