haskell - 如何使用 Warp 和 Aeson 通过 HTTP 传输 JSON

标签 haskell aeson haskell-warp

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

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

但是,warp 需要一个响应对象,而 Aeson 返回惰性 ByteStrings。

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

注意:这个问题故意不表现出任何研究成果,因为它是以问答形式回答的。如果您需要研究工作,请参阅我的回答。

最佳答案

我将在 HaskellWiki minimal warp example 上构建我的示例.

为了简单起见,我删除了路由等任何代码,用 stub 和注释替换了最相关的部分。

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

连接两个库的问题是,虽然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)

更新 05/01/2015: 修复 Warp/WAI 3.x 示例

关于haskell - 如何使用 Warp 和 Aeson 通过 HTTP 传输 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22183489/

相关文章:

list - 从 Haskell 中的元组列表中选择数据

parsing - 你如何以贪婪的方式使用 parsec?

json - 在 Haskell 中,如何解码可能属于两种不同类型的 JSON 值?

json - Haskell、Aeson - 如何调试实例?

Scala 的 Either 没有 `flatMap` 以及 Either.left/.right 的含义

multithreading - Haskell 中的 forkIO 和协程

haskell - 在 Aeson 中解析嵌套数组

javascript - Haskell WARP/WAI 服务器无法响应来自 Android 嵌入式 WebView 的 AJAX 调用

haskell - 扭曲 : Binding to Unix Domain Sockets

http - 在 Warp 中处理 HTTP GET 查询参数