2

How do I read a single field (by name) from a JSON object using Aeson, without writing any type class instance?

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
Filip Haglund
  • 13,919
  • 13
  • 64
  • 113
  • 1
    Could you please provide an example of what you precisely need?. As far as I know you can derive Aeson's type classes using `Generics`, so you don't need to write the instance – lsmor Jan 17 '19 at 10:31

2 Answers2

4

You can use decode to read a JSON ByteString as a Maybe Value, since Value already has a FromJSON instance:

*Q54233506 Q54233506> :set -XOverloadedStrings
*Q54233506 Q54233506> decode "{ \"foo\": \"bar\", \"baz\": 42 }" :: Maybe Value
Just (Object (fromList [("foo",String "bar"),("baz",Number 42.0)]))

From there, you can use one of the techniques described in this other answer to extract data from the Value.

For example, you can use the lenses from lens-aeson to extract the foo and baz values:

*Q54233506 Q54233506> :set -XOverloadedStrings
*Q54233506 Q54233506> v = decode "{ \"foo\": \"bar\", \"baz\": 42 }" :: Maybe Value
*Q54233506 Q54233506> v >>= (^? key "foo")
Just (String "bar")
*Q54233506 Q54233506> v >>= (^? key "baz")
Just (Number 42.0)

You can further compose this with _String or _Number to extract text or numbers:

*Q54233506 Q54233506> v >>= (^? key "foo") >>= (^? _String)
Just "bar"
*Q54233506 Q54233506> v >>= (^? key "baz") >>= (^? _Number)
Just 42.0
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
0

aeson-combinators package contains combinators that allow decoding/encoding JSON without the need for FromJSON / ToJSON instances.

This can be very convenient in general, for example, when decoding depends on other information such as HTTP header values.

In your case, you can use key :: Text -> Decoder a -> Decoder a combinator to get value of given key.

Check it out!

robert_peszek
  • 344
  • 2
  • 6