2012-01-28 6 views
1

Я использую scotty, который представляет собой синатра-подобную обертку вокруг WAI. Я хочу, чтобы тело необработанного запроса было байтовой строкой, поэтому я могу разобрать его как json. Близко следующее. Это похоже на другие вопросы о потребляя тела с помощью WAI, но отличается тем, что я хочу, чтобы тело в виде байтовой строки, и потому, что я нахожусь в другой монады, ActionMКак использовать кабель с WAI (необработанный корпус запроса)

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

ответ

1

requestBody не монадическое значение. Это просто функция, которая возвращает Conduit Source IO ByteString.

Чтобы использовать источник, используйте Data.Conduit.List.consume (или Data.Conduit.Lazy.lazyConsume). В результате вы получите список ByteString s. Чтобы затем выйти из монадного трансформатора ResourceT, используйте runResourceT. Полученный код:

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

нуждается Также jhickner в 'liftIO' прямо перед runResourceT. Благодаря! –

4

Для чего это стоит, новая версия Скотти (0.2.0) имеет метод «jsonData», чтобы сделать это для вас. Спасибо за использование!

2

Принятый ответ на самом деле не работает из-за способа работы lazyConsume. Он всегда будет возвращать пустой список. Вам необходимо использовать данные до, выходя из ResourceT, если вы используете lazyConsume.

В качестве альтернативы, вот как строго потреблять байтовой строки и вернуть его:

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

Это код, который, наконец, работать для меня, адаптировано из

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