I have come up with a way to not encode Maybe values that are empty, as shown in https://gist.github.com/2465584.
Is there an existing simple way to do this?
If not, should this become a feature in aeson?
let reply1 = Coord 123.4 20 (Just "foo")
BL.putStrLn (encode reply1)
let reply = Coord 123.4 20 Nothing
BL.putStrLn (encode reply)
+1. And one +1 for decoding. Many services omits fields instead set them null.
But how about generic decode?
I can't think of a way to do this that would always be safe for consumers of encoded data - null not being the same thing as a missing key/value pair.
Don't close this. This is really big headache.
The problem is that many applications omit the value instead set them null.
@akaspin, I can't figure out how to write code that satisfies both the people who want "don't encode anything if there's a Nothing!" and those who want "always encode Nothing as null!".
Also, even if I thought it would make sense to change the default, I would break existing apps. So if you need this fine a degree of control, use the existing support for custom encoders.
Not encode. decode is a problem.
The specific use case that drove me to the problem is where a JSON-encoded protocol is defined that always has certain core fields present, and then has a number of optional fields.
I would like to be able to have the symmetry of being able to start with a message having some fields with value Nothing, convert it to JSON, and then get it back the same way. And it has to interoperate with other implementations that do not understand the current null encoding.
To me a solution would be to extend the constructors in ToJSON to match the FromJSON ones, i.e. by introducing
(.=?) :: ToJSON a => Text -> a -> Pair
which only emits JSON if the Maybe value it is given is not Nothing.
Because it is a new operator, it cannot break existing code.
It looks like https://github.com/lassoinc/aeson-smart may provide this feature. Must investigate
@bos A field absent and field = null are distinct states, are they not? It'd be nice to be able to represent the former. Perhaps a Optional Value as an additional Value constructor?
field = null
for my case aeson-smart solved the problem. @bos, would you accept a patch that integrates aeson-smart's generator into aeson in a backwards-compatible way (usual disclaimers apply of course)?