yesod - 获取POST的请求体“Content-type:application / json”

时间:2011-04-24 01:36:27

标签: haskell yesod

使用yesod 0.8.0,我正在尝试从此示例请求中检索帖子消息的正文:

curl -v -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d '{"name":"oscar"}'    http://localhost:3000/user/xyz

在我的处理程序中,我看到的唯一方法是使用

(pp, files) <- runRequestBody

但由于内容类型的原因,这会失败。还有其他功能吗?

3 个答案:

答案 0 :(得分:14)

其他答案似乎很旧,并且在添加下面使用的功能之前。

postFooR :: Handler Value
postFooR = do
 foo <- requireJsonBody :: Handler Foo -- get the json body as Foo (assumes FromJSON instance)
 returnJson foo -- return json (assumes ToJSON instance)

答案 1 :(得分:8)

Here's how to do it now。对于将来的版本,我希望添加一些便利包装器;对此的意见表示赞赏。

解释:每个处理函数都存在于GGHandler sub master (Iteratee ByteString IO) monad中。这是相当复杂的,但它意味着它是一个围绕一个Iteratee的Handler monad变换器,它接收一个ByteStrings流。 ByteStrings流是原始请求主体。

因此我们需要使用枚举器的消费函数来获取整个ByteStrings流并将它们存储为列表。我们需要使用提升功能将其提升到内部monad(Iteratee)。 L.fromChunks然后从严格的ByteStrings列表转换为惰性ByteString,您可以使用任何任意JSON库进行解析(Yesod正在标准化aeson)。

我的猜测是我能提供的最方便的功能是parseRequestJson :: GGHandler s m (Iteratee ByteString IO) (Maybe Data.Aeson.Value)。我可以在yesod-json的点发布中添加它。

答案 2 :(得分:3)

在Yesod 1.0+中(可能更早,不确定),以下似乎有效:

postRootR = do
    wr <- waiRequest
    bss <- lift $ lazyConsume $ requestBody wr
    let requestBody = L.fromChunks bss