Haskell使用Network.HTTP.Req发起带OAuth2的GET请求报错求助
问题1:编译报错No instance for (FromJSON Data.ByteString.Char8.ByteString)
这个报错的原因是jsonResponse要求返回的body类型实现了FromJSON类型类,你当前代码直接把responseBody v当成ByteString打印,而ByteString默认没有FromJSON实例,有两种解决方法:
- 定义匹配API返回结构的自定义数据类型,派生
Generic和FromJSON实例,用这个类型接收响应 - 直接用Aeson提供的通用
Value类型接收JSON(Value自带FromJSON实现),示例写法如下:
v <- req GET 你的路径 NoReqBody jsonResponse (oAuth2Bearer tok) :: Req (JsonResponse Value)
如果只是想打印原始JSON内容,用bsResponse接收后直接打印也是合理的。
问题2:400错误endpoint doesnt exist
查看报错日志里的请求路径是/v1/userprincipals%3Ffields=streamerConnectionInfo,问题出在你把查询参数直接写到了/: 后面的路径段里,req的/: 操作符会自动对内容做URL编码,所以?被转成了%3F,导致整个查询参数被当成了路径的一部分,后端找不到对应接口。
req库添加查询参数需要用=?操作符写到请求配置项里,修正后的请求写法如下:
v <- req GET (https "api.tdameritrade.com" /: "v1" /: "userprincipals") NoReqBody bsResponse -- 可按需求替换为jsonResponse ( "fields" =: ("streamerConnectionInfo" :: Text) <> oAuth2Bearer tok )
修正后完整可运行示例代码
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} module Main where import Control.Monad.IO.Class import Data.ByteString.Char8 (pack, putStrLn) import Network.HTTP.Req import Prelude hiding (putStrLn) tok :: ByteString tok = pack "accesstoken" main :: IO () main = runReq defaultHttpConfig $ do v <- req GET (https "api.tdameritrade.com" /: "v1" /: "userprincipals") NoReqBody bsResponse ("fields" =: ("streamerConnectionInfo" :: Text) <> oAuth2Bearer tok) liftIO $ putStrLn (responseBody v)
修正后请求就能匹配到正确接口,会返回预期的认证令牌错误。
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

