haskell - 在 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 的提示吗?
解决方案
所以最终我实现了我一直在寻找的东西——哇,我真的为我感到骄傲......好吧,对于那些会寻找同样事情的人来说,我已经设法做的事情,概括一下我的主要问题是逃避 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 总是在底部?
推荐阅读
- vb.net - StreamWriter 将文件保存为 ANSI
- html - 图像映射的闪烁边框
- mysql - 错误 2020 (HY000):尝试从表中检索数据时,数据包大于“max_allowed_packet”字节
- raspberry-pi - 是否有任何带有 Alexa 语音服务的家庭自动化演示?
- javascript - 过滤 ng-repeat 时如何在过滤器上使用布尔变量?
- symmetricds - SymmetricDS:保持单独的自动增量计数器
- sql - 错误(6,87):PLS-00103:在预期以下/复合触发器之一时遇到符号“JOIN”
- docker - apt-get update 签名验证出错
- c# - 在它所在的表单被关闭和处理之后执行的代码
- spring-boot - 为什么程序在通过 Soap 服务进行调用时返回无法识别的回调