Suppose I have a JSON like this:
{
data: {...}
}
and {...}
represents a model of mine. How could
get my model in this case in the Handler? For instance, the following will not work obviously:
putMyEntityR :: Handler ()
putMyEntityR = do
(Entity id _) <- (...) -- getting the Key
e <- requireJsonBody :: Handler MyEntity
runDB $ replace id e
sendResponseStatus status204 ("UPDATED" :: Text)
How can I read the JSON
, take the data
object, and only then decode it?
There was some more discussion of this question on a Github Issue, which I'm adding as an answer here because it's more fleshed out. Here's what we arrive at for the Handler function using the helper functions defined below:
These functions take the request body and parse it into an aeson
Value
:These helper functions are used to parse that
Value
into a record:Commentary
aeson-lens
I didn't use
aeson-lens
, but the code is pretty similar with or without it, since we're just going one key deep.aeson-lens
would make things nicer if we were traversing deeper into the JSON.Comparison to wrapper definition
Once you get the helper functions defined, you still have a couple lines to parse a
Value
, then lookup thedata
key, then create your record. You can do things to make this shorter, but ultimately the wrapper that @Carsten recommended would be of similar length with less complexity, imo.This was too large to fit in my comment above (using lens-aeson)
and as Carsten mentioned, you'll still need to provide a FromJSON instance of your model