Reputation: 33891
Full minimal example project available here: https://github.com/chrissound/217
I've read through https://docs.servant.dev/en/v0.16/cookbook/using-free-client/UsingFreeClient.html
Where I end up with:
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'
However this approach seems to just output the below:
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
}
While I'm expecting a body to have some text present. The reason I expect this - because if send a request to a server and debug/inspect that - I do see a body with text present. So my question here is, why is servant saying the rawBody
is False
, and how do I actually get it to show the body?
The non debug code which actually sends the HTTP request is:
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
Upvotes: 3
Views: 460
Reputation: 657
The answer is that it's hard and most solutions are not usable for applications handling many requests. You need to read the entire body into something like an MVar which you can then use. You can do this through a Middleware. However, since you consume the entire body you will need to put it back into the stream if it's suppose to be used by another middleware etc. This is still an open issue on the servant repository: https://github.com/haskell-servant/servant/issues/1120
Upvotes: 1