4

我想创建一个在 Haskell 上运行的高性能基于 HTTP 的 API,使用warp作为 HTTP 后端。

服务器应根据请求返回 JSON 数据。此数据应使用Aeson序列化

然而,warp需要一个响应对象,而 Aeson 返回lazy ByteStrings。

如何将两个库绑定在一起?对于这个问题的范围,我对查询解析或路由不感兴趣,但在一个示例中,如何将两个库绑定在一起以提供具有正确标头的正确 JSON。

注意:这个问题故意不显示任何研究工作,因为它是以问答方式回答的。如果您需要研究工作,请参阅我的答案。

4

1 回答 1

6

我将在HaskellWiki 最小扭曲示例上构建我的示例

为了简单起见,我删除了任何代码,如路由,用存根替换最相关的部分,并在哪里放置什么的注释。

我们将在本例中序列化的 JSON 数据是 list ["a","b","c"]。任何 URL 都将返回相同的响应(= JSON)。

连接这两个库的问题是,虽然warp需要 BlazeBuilder才能正确构建其响应,而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)

2015 年5 月 1 日更新:修正 Warp/WAI 3.x 的示例

于 2014-03-04T21:31:01.137 回答