You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:18:03