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

Osc*_*car 13 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
Run Code Online (Sandbox Code Playgroud)

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

(pp, files) <- runRequestBody
Run Code Online (Sandbox Code Playgroud)

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

Lux*_*ode 15

其他答案似乎很旧,并且在添加下面使用的函数之前.

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)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您也可以执行“ requireJsonBody :: Handler Value”,然后,如果不必为“ Foo”编写新的数据类型而烦恼,只需使用Lens提取所需的字段。 (3认同)

Mic*_*man 8

这是现在的方法.对于将来的版本,我希望添加一些便利包装器; 对此的意见表示赞赏.

解释:每个处理函数都存在于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的一个点发布中添加它.