I have an application that gets JSON response from an API and I'm trying to get a specific key from that response. The working code looks as below:
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Data.Aeson
import Network.HTTP.Req
tinyUIDRequest :: String -> Req (JsonResponse Object)
tinyUIDRequest url = let payload = object [ "url" .= url ]
in req
POST
(https "tinyuid.com" /: "api" /: "v1" /: "shorten") (
ReqBodyJson payload)
jsonResponse
mempty
main :: IO ()
main = do
response <- runReq defaultHttpConfig (tinyUIDRequest "http://google.com")
let body = responseBody response
print body
And the function to process the response should look similar to:
tinyUIDResponseHandler :: HttpResponseBody (JsonResponse Object) -> String
tinyUIDResponseHandler r = case lookup "result_url" r of
Just url -> url
Nothing -> ""
unfortunately I'm not able to figure out how to transform HttpResponseBody (JsonResponse Object) to something like hashmap/list and find a proper key. I was checking the documentation and req source code but maybe, as a beginner in Haskell, I don't know exactly what to look for to understand the internals of the response type.
HttpResponseBodyis a red herring. It's an associated type, andHttpResponseBody (JsonResponse a)is the same as justa, soHttpResponseBody (JsonResponse Object)is really justObject. As such, once you havebody,req's job is done, and it's now justaesonthat you need to be concerned with.Since
bodyis anObjectand not a list of tuples, you can't use Prelude'slookupon it. If your Aeson version is older than 2, thenObjectis justHashMap Text Value, so do this instead:If your Aeson version is 2 or newer, then
ObjectisKeyMap Value, so do this instead:In either case,
tinyUIDResponseHandler bodywill then be the value you want, so for example, you could doprint (tinyUIDResponseHandler body).