首页 > 解决方案 > 在 Spock Web 服务器上打印字节串

问题描述

在 Spock 上运行的网络服务器(例如本地主机)上可视化字节字符串主体

我的目标:创建网站并查看字节串(转换为文本) 框架:Http Simple 用于为我的服务器执行对 restAPI Spock 的请求 我不想创建 JSON,因为我需要在创建之前操作/检查我的响应JSON 结构。一般的想法是我想使用响应正文来构造一个 JSON 查询结构(用户将能够编写他的问题),该结构将被发送到 restAPI 网站。

我设法建立一个这样的请求:

    connect = do
        request' <- (parseRequest "http://localhost")
        let request = setRequestMethod "POST"
                    $ setRequestHost (S8.pack ("xx.xxx.xxx.xxx"))
                    $ setRequestPath "/api/Integration/Login"
                    $ setRequestBodyJSON me
                    $ setRequestPort 1000
                    $ request'
        response <- httpJSON request
        return (getResponseBody response :: Auth)

然后我用它来查询API页面

getRequest :: RequestPath -> HtmlT IO L.ByteString
getRequest rpath = do
        atoken <- liftIO connect
        request' <-  liftIO (parseRequest "http://localhost")
        let request = setRequestMethod "POST"
                    $ setRequestHost (S8.pack ("xx.xxx.xxx.xxx"))
                    $ setRequestPort 1000
                    $ setRequestPath (S8.pack ("/api/Integration/" ++ rpath))
                    $ addRequestHeader hAuthorization (S8.pack (unpack (token_type (atoken)) ++ " " ++ unpack (access_token (atoken))))
                    $ setRequestBodyJSON r1
                    $ request'
        response <- httpLBS request
        return (getResponseBody (response))

然后我跟着一个简短的 SpockM monad:

app1 = do get root $ text "root"
          fct 

fct 等于

fct = do get "/further" $ lucidIO ( fmap TL.decodeUtf8 (getRequest "GetProperties"))

一切都编译得很好,我什至可以在 GHCI 中看到调用的结果,例如:(connect >>= (\ x -> print x)与 getRequest "GetProperties" 相同)我不明白的是 lucidIO 应该给我一个 ActionCtxtT ctx mb 类型,它完全适合 a处理程序(例如,像中的文本函数do get ... $ text -> ActionCtxT ctx m a)并且应该由 main() 中的 spock 函数处理,即runSpock 8080 (spock spockCfg app1) 我试图摆脱 ByteString 'ending' 类型,用 () 替换它,以便尽可能接近地模仿这Html ()在我研究的许多示例中出现并工作的类型。所有解析和请求构建都是使用 HTTP.Simple 完成的(我知道它不是很优雅,例如它必须工作),它把我从一个 monad 中拉出来(由于第一个函数 'parseRequest' -> m Request)来自在 lucidIO 之前我无法逃脱 - 可能是我选择了错误的 Monad(即 IO :但使用 IO 我能够检查 ghci 中的所有内容)。你能给我一些关于如何在我的浏览器中打印这个 ByteString 的提示吗?

标签: haskellbytestringhaskell-spock

解决方案


所以最终我实现了我一直在寻找的东西——哇,我真的为我感到骄傲......好吧,对于那些会寻找同样事情的人来说,我已经设法做的事情,概括一下我的主要问题是逃避 IO monad (我的选择可能并不聪明,但仍然如此)由于使用了 HTTP.simple 库中的请求解析器,我陷入了困境。我的代码略有变化,但总体思路保持不变:

构建响应查询:

getResponseMethod  :: RequestPath -> RequestBody -> IO (Maybe Value) 

得益于解码功能(aeson 包),从中获得了一个可能值(包装在 IO 中,但没关系)

然后是我的小 spock 服务器:

main :: IO ()
main = do
    spockCfg <- defaultSpockCfg () PCNoDatabase ()
    runSpock 8080 (spock spockCfg app)

我做了很多工作来获得app -> SpockM () () () () 我能想象到的最简单的应用程序的权利:

app = do get root $ text "Hello!"

注意到文本功能正在产生一个MonadIO m => ActionCtxT cxt m a monad所以我的想法是,如果我“洒”一些聪明的 LiftIO 东西,它应该可以完成这项工作。

我创建了一个辅助函数:

extrct :: MonadIO m => ActionCtxT ctx m Text 
extrct = liftIO $ do
     a <-  getResponseMethod "GetProperties" r1
     return (pack $ show a)

并用手调整我的应用程序

app :: SpockM () () () ()
app = do get root $ do
            a <- extrct
            text a

最后,我能够在我的 spock 本地网络服务器上看到 Maybe Value :: JSON 的字符串表示形式。这就是我一直在寻找的。现在我可以着手清理我的代码了。据我了解,使用 liftIO 会将 IO monad 放在 Monad Stack 的正确位置,因为 IO 总是在底部?


推荐阅读