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

发布于 2024-11-02 19:04:01 字数 333 浏览 4 评论 0原文

使用 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

But 由于内容类型而失败。还有其他函数可以做到这一点吗?

Using yesod 0.8.0, I'm trying to retrieve the body of a post message from this example request:

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

in my handler the only way I see it is to use

(pp, files) <- runRequestBody

But this fails because of the content type. Is there another function to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情哥ㄟ 2024-11-09 19:04:01

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

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)

The other answers seem to be pretty old and from before the functions used below were added.

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)
樱娆 2024-11-09 19:04:01

这是现在的操作方法。对于未来的版本,我希望添加一些方便的包装;感谢对此的意见。

解释:每个处理程序函数都位于 GGHandler sub master (Iteratee ByteString IO) monad 中。这相当复杂,但它的意思是它是一个围绕接收 ByteString 流的 Iteratee 的 Handler monad 转换器。该字节字符串流是原始请求正文。

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

我的猜测是,我可以提供的最方便的函数是 parseRequestJson :: GGHandler sm (Iteratee ByteString IO) (Maybe Data.Aeson.Value)。我可以在 yesod-json 的点发布中添加这一点。

Here's how to do it now. For future releases, I'm hoping to add some convenience wrappers; input on this is appreciated.

The explanation: Each handler function lives in a GGHandler sub master (Iteratee ByteString IO) monad. That's fairly complicated, but what it means is that it's a Handler monad transformer around an Iteratee that receives a stream of ByteStrings. That stream of ByteStrings is the raw request body.

So we need to use enumerator's consume function to take that entire stream of ByteStrings and store them as a list. And we need to use the lift function to lift this to the inner monad (the Iteratee). L.fromChunks then converts from a list of strict ByteStrings to a lazy ByteString, which you can parse with any arbitrary JSON library (Yesod is standardizing on aeson).

My guess is that the most convenient function I could provide would be parseRequestJson :: GGHandler s m (Iteratee ByteString IO) (Maybe Data.Aeson.Value). I can add that in a point release of yesod-json.

蓝礼 2024-11-09 19:04:01

在 Yesod 1.0+(也许更早,不确定)中,以下内容似乎有效:

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

In Yesod 1.0+ (and maybe earlier, not sure), the following appears to work:

postRootR = do
    wr <- waiRequest
    bss <- lift $ lazyConsume $ requestBody wr
    let requestBody = L.fromChunks bss
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文