在Spock上运行的网络服务器上可视化字节正文(例如本地主机)
我的目标:创建网站并查看字节串(转换为文本) 框架:Http 简单,用于执行对 restAPI 的请求 斯波克为我的服务器 例如,我不想创建 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 m b 类型,它完全适合处理程序的类型(例如像do get ... $ text -> ActionCtxT ctx m a
中的文本函数),并且应该由 main() 中的 spock 函数处理,即runSpock 8080 (spock spockCfg app1)
我试图摆脱 ByteString "ending"类型,将其替换为 (),以便尽可能接近在我研究的许多示例中出现并工作的Html ()
类型。 所有解析和请求构建都是使用 HTTP 完成的。简单(它不是很优雅,我知道例如它只需要工作),它把我从一个 monad 开始(由于第一个函数"parseRequest"-> m Request),直到 lucidIO 我才能逃脱 - 可能是我选择了错误的 Monad(即 IO:但使用 IO,我能够检查 ghci 中的所有内容)。你能给我一些关于如何在浏览器中打印这个字节字符串的提示吗?
所以终于我实现了我一直在寻找的东西 - 哇,我真的为我感到骄傲...... 好吧,对于那些会寻找同样的东西的人来说,我设法做的,回顾一下我的主要问题是逃避 IO monad(我的选择可能不聪明,但仍然),由于使用 HTTP.simple 库的请求解析器,我被困在其中。 我的代码发生了一些变化,但总体思路保持不变:
构建响应查询:
getResponseMethod :: RequestPath -> RequestBody -> IO (Maybe Value)
由于解码功能(AESON包),从中获得了一个可能的值(包装在IO中,但这没关系)
然后是我的小斯波克服务器:
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 本地网络服务器上看到 May Value :: JSON 的字符串表示形式。这就是我一直在寻找的。现在我可以清理我的代码了。据我了解,使用 liftIO 会将 IO monad 放在 Monad 堆栈中的位置,这是因为 IO 总是在底部?