如何检查/调试服务客户端请求的正文?



此处提供完整的最小示例项目:https://github.com/chrissound/217

我已经通读了https://docs.servant.dev/en/v0.16/cookbook/using-free-client/UsingFreeClient.html

我最终的目标:

type API = "square"
:> Capture "n" Int
:> ReqBody '[JSON] ClientInfo
:> Get '[JSON] Int
api :: Proxy API
api = Proxy
myapitest = I.client api
getSquare :: Int -> ClientInfo -> Free ClientF Int
getSquare = Servant.Client.Free.client api
test :: IO ()
test = case getSquare 12 (ClientInfo "" "" 123 []) of
Pure n ->
putStrLn $ "ERROR: got pure result: " ++ show n
Free (Throw err) ->
putStrLn $ "ERROR: got error right away: " ++ show err
Free (RunRequest req k) -> do
burl <- parseBaseUrl "http://localhost:8000"
mgr <- HTTP.newManager HTTP.defaultManagerSettings
let req' = I.requestToClientRequest burl req
putStrLn $ "Making request: " ++ show req'

然而,这种方法似乎只是输出以下内容:

Making request: Request {
host                 = "localhost"
port                 = 8000
secure               = False
requestHeaders       = [("Accept","application/json;charset=utf-8,application/json"),("Content-Type","application/json;charset=utf-8")]
path                 = "/square/12"
queryString          = ""
method               = "GET"
proxy                = Nothing
rawBody              = False
redirectCount        = 10
responseTimeout      = ResponseTimeoutDefault
requestVersion       = HTTP/1.1
}

当我期待一个身体有一些文本呈现。我期望这样做的原因是——因为如果向服务器发送请求并调试/检查它——我确实看到了一个带有文本的正文。所以我的问题是,为什么仆人说rawBodyFalse,我怎么才能真正让它展示身体?

实际发送HTTP请求的非调试代码是:

main :: IO ()
main = do
putStrLn "Hello, Haskell!"
run
test
queries = myapitest 10 (ClientInfo "" "" 123 [])
run :: IO ()
run = do
manager' <- newManager defaultManagerSettings
res <- runClientM queries (mkClientEnv manager' (BaseUrl Http "localhost" 8000 ""))
case res of
Right (message) -> do
pPrint message
Left err -> do
putStrLn $ "Error: "
pPrint err

答案是这很难,而且大多数解决方案都不适用于处理许多请求的应用程序。你需要把整个身体读成一个MVar,然后你就可以使用它了。您可以通过中间件执行此操作。然而,由于您消耗了整个主体,如果假设它被另一个中间件等使用,则需要将其放回流中。这仍然是服务存储库中的一个悬而未决的问题:https://github.com/haskell-servant/servant/issues/1120

最新更新