如何使用WAI(原始请求体)消耗管道

时间:2012-01-28 02:59:21

标签: haskell monads conduit haskell-wai

我正在使用scotty,这是围绕WAI的类似sinatra的包装器。我想将原始请求主体作为字节字符串,以便我可以将其解析为json。以下是关闭。这类似于使用WAI消耗身体的其他问题,但是因为我希望身体作为字节串,并且因为我在不同的monad,ActionM

import Network.Wai (requestBody)
import Web.Scotty (ActionM, request, text)

bodyExample :: ActionM ()
bodyExample = do
    r <- request
    bss <- requestBody r -- this needs a lift or something
    text "ok"
    ...

它显然不起作用,我想我需要某种电梯或什么,但我不知道该用什么。 liftIO不对,lift给了我奇怪的错误。

http://hackage.haskell.org/packages/archive/scotty/0.0.1/doc/html/Web-Scotty.html

http://hackage.haskell.org/packages/archive/wai/latest/doc/html/Network-Wai.html

4 个答案:

答案 0 :(得分:4)

对于它的价值,新版本的Scotty(0.2.0)有一个'jsonData'方法为你做这个。感谢您的使用!

答案 1 :(得分:2)

由于lazyConsume的工作方式,接受的答案实际上无法奏效。它将始终返回一个空列表。如果您使用ResourceT,则需要在退出lazyConsume之前使用数据。

作为替代方案,这里是如何严格使用bytestring并返回它:

rawRequestBody :: Request -> IO B.ByteString
rawRequestBody req = mconcat <$> runResourceT (requestBody req $$ consume)

答案 2 :(得分:1)

requestBody不是monadic值。它只是一个返回Conduit Source IO ByteString的函数。

要使用来源,请使用Data.Conduit.List.consume(或Data.Conduit.Lazy.lazyConsume)。作为结果,您将获得ByteString的列表。要退出ResourceT monad转换器,请使用runResourceT。结果代码:

bss <- liftIO . runResourceT . lazyConsume . requestBody $ r
bss :: [ByteString]

答案 3 :(得分:0)

这是最终适合我的代码,改编自jhickner的

rawRequestBody req = mconcat <$> (requestBody req $$ consume)