如何处理Haskell请求中的HttpResponseBody?
How to process HttpResponseBody in Haskell req?
我有一个从 API 获得 JSON 响应的应用程序,我正在尝试从该响应中获得特定的密钥。工作代码如下所示:
{-# 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
处理响应的函数应该类似于:
tinyUIDResponseHandler :: HttpResponseBody (JsonResponse Object) -> String
tinyUIDResponseHandler r = case lookup "result_url" r of
Just url -> url
Nothing -> ""
不幸的是,我无法弄清楚如何将 HttpResponseBody (JsonResponse Object)
转换为 hashmap/list 之类的东西并找到合适的密钥。我正在检查 the documentation and req source code 但也许,作为 Haskell 的初学者,我不知道究竟要寻找什么来理解响应类型的内部结构。
HttpResponseBody
是一个转移注意力的问题。它是一个关联类型,HttpResponseBody (JsonResponse a)
与 a
相同,因此 HttpResponseBody (JsonResponse Object)
实际上只是 Object
。因此,一旦您有了 body
,req
的工作就完成了,现在您只需要关心 aeson
。
由于 body
是一个 Object
而不是元组列表,您不能在其上使用 Prelude 的 lookup
。如果你的 Aeson 版本早于 2,那么 Object
就是 HashMap Text Value
,所以这样做:
import Data.Text
import qualified Data.HashMap.Strict as HM
tinyUIDResponseHandler :: Object -> Text
tinyUIDResponseHandler r = case HM.lookup "result_url" r of
Just (String url) -> url
_ -> ""
如果您的 Aeson 版本是 2 或更高版本,则 Object
是 KeyMap Value
,因此请改为:
import Data.Text
import qualified Data.Aeson.KeyMap as AKM
tinyUIDResponseHandler :: Object -> Text
tinyUIDResponseHandler r = case AKM.lookup "result_url" r of
Just (String url) -> url
_ -> ""
在任何一种情况下,tinyUIDResponseHandler body
都是您想要的值,例如,您可以 print (tinyUIDResponseHandler body)
.
我有一个从 API 获得 JSON 响应的应用程序,我正在尝试从该响应中获得特定的密钥。工作代码如下所示:
{-# 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
处理响应的函数应该类似于:
tinyUIDResponseHandler :: HttpResponseBody (JsonResponse Object) -> String
tinyUIDResponseHandler r = case lookup "result_url" r of
Just url -> url
Nothing -> ""
不幸的是,我无法弄清楚如何将 HttpResponseBody (JsonResponse Object)
转换为 hashmap/list 之类的东西并找到合适的密钥。我正在检查 the documentation and req source code 但也许,作为 Haskell 的初学者,我不知道究竟要寻找什么来理解响应类型的内部结构。
HttpResponseBody
是一个转移注意力的问题。它是一个关联类型,HttpResponseBody (JsonResponse a)
与 a
相同,因此 HttpResponseBody (JsonResponse Object)
实际上只是 Object
。因此,一旦您有了 body
,req
的工作就完成了,现在您只需要关心 aeson
。
由于 body
是一个 Object
而不是元组列表,您不能在其上使用 Prelude 的 lookup
。如果你的 Aeson 版本早于 2,那么 Object
就是 HashMap Text Value
,所以这样做:
import Data.Text
import qualified Data.HashMap.Strict as HM
tinyUIDResponseHandler :: Object -> Text
tinyUIDResponseHandler r = case HM.lookup "result_url" r of
Just (String url) -> url
_ -> ""
如果您的 Aeson 版本是 2 或更高版本,则 Object
是 KeyMap Value
,因此请改为:
import Data.Text
import qualified Data.Aeson.KeyMap as AKM
tinyUIDResponseHandler :: Object -> Text
tinyUIDResponseHandler r = case AKM.lookup "result_url" r of
Just (String url) -> url
_ -> ""
在任何一种情况下,tinyUIDResponseHandler body
都是您想要的值,例如,您可以 print (tinyUIDResponseHandler body)
.