Rafael Klynger
Rafael Klynger

Reputation: 1

How to manipulate data from json in Yesod?

If I have this code, how do I change the age of the JSON sent from the post request and then return it? My experience with Haskell in general is really poor so, I don't know if my problem comes from lacking of knowledge in the Yesod framework of in the language itself.

{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE QuasiQuotes           #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}

module Handler.Home where
import Data.Aeson
import Data.Text (Text)
import Yesod


data HelloWorld = HelloWorld

mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET POST
|]

instance Yesod HelloWorld

data Person = Person
    { name :: Text
    , age :: Int
    } deriving (Eq, Show)

instance ToJSON Person where
    toJSON (Person n a)  = object
        [ "name" .= n
        , "age"  .= a
        ]

instance FromJSON Person where
    parseJSON = withObject "Person" $ \v -> Person
        <$> v .: "name"
        <*> v .: "age"

getHomeR :: Handler Value
getHomeR = returnJson $ Person "Rafael" 21


postHomeR :: Handler Value
postHomeR = do
    json_payload <- requireJsonBody :: Handler Person
    returnJson json_payload

main :: IO ()
main = warp 3000 HelloWorld

Upvotes: 0

Views: 227

Answers (1)

Mor A.
Mor A.

Reputation: 4646

json_payload is a Person, so you can just use the record update syntax.
For instance the value json_payload { age = 32 } has all the fields of json_payload except the age field which is 32.

So you can rewrite postHomeR as

postHomeR = do
  json_payload <- requireJsonBody :: Handler Person
  let modified = json_payload { age = 32 }
  returnJson modified

Or

postHomeR = do
  json_payload <- requireJsonBody :: Handler Person
  returnJson (json_payload { age = 32 })

The parentheses are not required but I think it makes it clearer, rather than having to go and check the syntax rules for the precedence.

Upvotes: 2

Related Questions