Как доставить JSON через HTTP, используя Warp с Aeson
Я хочу создать высокопроизводительный API на основе HTTP, работающий на Haskell, используя warp в качестве HTTP-бэкенда.
Сервер должен возвращать данные JSON по запросу. Эти данные должны быть сериализованы с использованием Aeson
Тем не менее, деформация требует объекта ответа, в то время как Aeson возвращает ленивый ByteString
s.
Как я могу связать обе библиотеки вместе? В этом вопросе меня интересует не разбор или маршрутизация запросов, а пример того, как связать обе библиотеки, чтобы получить правильный JSON с правильными заголовками.
Примечание: этот вопрос намеренно не требует каких-либо исследований, так как на него был дан ответ Q&A-style-ish. Смотрите мой ответ, если вам требуется исследовательская работа.
1 ответ
Я построю свой пример на примере минимальной деформации HaskellWiki.
Ради простоты я удалил любой код, такой как маршрутизация, заменив наиболее важные части заглушками и комментариями, где что размещать.
Данные JSON, которые мы будем сериализовывать в этом примере, представляют собой список ["a","b","c"]
, Тот же ответ (= JSON) будет возвращен для любого URL.
Проблема в соединении обеих библиотек заключается в том, что в то время как Warp требует Blaze Builder
правильно построить свой ответ, в то время как Aeson возвращает (как вы сказали) ленивый ByteString
, Соответствующая функция для соединения обоих называется fromLazyByteString
,
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import Data.Text (Text)
import Network.Wai
import Network.Wai.Handler.Warp
import Network.HTTP.Types (status200)
import Network.HTTP.Types.Header (hContentType)
import Blaze.ByteString.Builder.ByteString (fromLazyByteString)
import qualified Data.ByteString.UTF8 as BU
main = do
let port = 3000
putStrLn $ "Listening on port " ++ show port
run port app
app :: Application
app req f = f $
case pathInfo req of
-- Place custom routes here
_ -> anyRoute
-- The data that will be converted to JSON
jsonData = ["a","b","c"] :: [Text]
anyRoute = responseLBS
status200
[(hContentType, "application/json")]
(encode jsonData)
Обновление 01.05.2015: пример исправления для Warp/WAI 3.x