How to create JSON Rest API with Happstack? JSON body?
Asked Answered
H

1

8

I'm trying to create a JSON REST api using Happstack. It should allow POSTS with a JSON body. How can I do this? All the functions in happstack's API seem to look things up based on parameter name. It thinks the body is always url-encoded.

If it isn't possible with Happstack, which framework should I use?

Hyssop answered 14/1, 2012 at 22:16 Comment(0)
H
11

Alright, here's what I figured out.

{-# LANGUAGE OverloadedStrings, DeriveDataTypeable #-}
import qualified Data.ByteString.Lazy.Char8 as L
import Happstack.Server
import Happstack.Server.Types
import Control.Monad.IO.Class (liftIO)

import Data.Data (Data, Typeable)

-- easiest to serialize/deserialize objects
data Unit = Unit { x :: Int, y :: Int } deriving (Show, Eq, Data, Typeable)

-- put this function in a library somewhere
getBody :: ServerPart L.ByteString
getBody = do
    req  <- askRq 
    body <- liftIO $ takeRequestBody req 
    case body of 
        Just rqbody -> return . unBody $ rqbody 
        Nothing     -> return "" 

myRoute :: ServerPart Response
myRoute = do
    body <- getBody -- it's a ByteString
    let unit = fromJust $ A.decode body :: Unit -- how to parse json
    ok $ toResponse $ A.encode unit -- how to send json back. 
Hyssop answered 14/1, 2012 at 22:42 Comment(3)
That is the correct solution. The code in Happstack.Server.RqData is for dealing with url-encoded and multiple/form-data submissions. If you just need the raw request body, then you just take it with takeRequestBody. At some point in time there will be an AJAX / JSON section in the crash course.Schistosome
@Sean Clark, I see <- used extensively in this code. Is it an assignment statement (or) more than it?? like, body <- getBody. getBody's return value is given to body variableEqui
@MadhavanKumar it's more than that. See haskell monads and do-notationAquaplane

© 2022 - 2024 — McMap. All rights reserved.