這是我嘗試連接到TDAmeritrade的api 來接收一個json回應。
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Lib
import Wuss
import Control.Concurrent
import Control.Monad
import Data.Text
import Network.WebSockets
import Network.Connection
import Network.WebSockets.Stream
import Data.Text.Lazy
import Data.ByteString
import Lens.Micro.GHC.Internal
import Network.Curl
import Data.ByteString.Lazy.UTF8
import Network.HTTP.Req
import Control.Monad
import Control.Monad.IO.Class
import Data.Aeson
import Data.Maybe
import Data.Monoid
import GHC.Generics
import Network.HTTP.Req
import Data.ByteString.Char8
tok = Data.ByteString.Char8.pack "accesstoken"
main :: IO ( )
main = runReq defaultHttpConfig $do
v <- req GET (https "api.tdameritrade.com" /: "v1" /: "userprincipals? fields=streamerConnectionInfo") (NoReqBody) jsonResponse (oAuth2Bearer tok)
liftIO $ Data.ByteString.Char8.putStrLn(responseBody v)
如果操作正確,回應應該只給出一個錯誤,即auth token不正確,因為我故意不在這里提供一個有效的token。"accesstoken"
如果我使用bsResponse而不是jsonResponse,它會進行型別檢查,但它不會用jsonResponse進行型別檢查。來自TDAmeritrade的回應將是JSON格式。
這是一個錯誤:
這是一個錯誤。
No instance for (FromJSON Data. ByteString.Char8.ByteString)
產生于使用of'req'。
如果我使用bsResponse,結果是這樣的:
port = 443.
secure=True
requestHeaders = [("Authorization","<REDACTED>") ]
path = "/v1/userprincipals?fields=streamerConnectionInfo")
queryString = ""/span>
方法 = "GET"/span>
代理 = Nothing
rawBody = False[/span
redirectCount =10
responseTimeout = ResponseTimeoutDefault
requestVersion = HTTP/1.1。
}
(StatusCodeException (Response {responseStatus = Status {statusCode = 400, statusMessage = "Bad Request"/span>}, responseVersion = HTTP/1. 1, responseHeaders = [("Date"/span>,"Wed, 08 Sep 2021 15:27: 41 GMT"),("Content-Type","application/json"),("Content-Length", "78"),("Connection","keep-alive"),("Host", "api. tdameritrade. com"),("X-Forwarded-Port","9002") 。 ("X-Forwarded-Proto","http"),("接受編碼"。 "gzip"),("Authorization","Bearer accesstoken"),("NS-Proxy-Client-IP", "82. 46.185. 98"),("Access-Control-Allow-Origin",""),("Access-Control-Allow-Headers"。 "origin, x-requested-with, accept, authorization, content-type, correlationid, apikey, application-name")。) ("Access-Control-Max-Age","3628800"),("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS, HEAD, PATCH"),("X-Xss-Protect","1; mode=block"),("X-Content-Type-Options","nosniff"),("X-Frame-Options", "SAMEORIGIN"),("Content-Security-Policy","frame-ancestors 'self'") 。 ("Cache-Control","no-cache,no-store,must-revalidate"),("Strict-Transport-Security", "max-age=31536000")], responseBody = (), responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}) "
{
"錯誤": "該端點不存在。"
}
"))
作為參考,終端中的這個curl命令產生了正確的回應:
curl -X GET -header "Authorization: Bearer authorizationtoken" "https://api.tdameritrade.com/v1/userprincipals?fields=streamerConnectionInfo"/span>
我完全迷失了方向。請幫助我
uj5u.com熱心網友回復:
為了解決你的即時錯誤,你必須使用(=:)函式構建請求引數,而不是手動撰寫? fields=streamerConnectionInfo部分。而且你還需要禁用錯誤狀態代碼檢查。這是復制你的curl命令的作業代碼:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString.Char8
import Network.HTTP.Req
import Control.Monad.IO.Class
import Data.Text
tok = Data.ByteString.Char8.pack "accesstoken"
main :: IO ( )
main = runReq defaultHttpConfig { httpConfigCheckResponse = _ _ -> Nothing } $ do
v <- req GET (https "api.tdameritrade.com" /: "v1" /: "userprincipals") (NoReqBody) bsResponse ("field" =: ("streamerConnectionInfo" :: Text) <> oAuth2Bearer tok)
liftIO $ Data.ByteString.Char8.putStrLn (responseBody v)
另一個問題是從產生的JSON體中訪問欄位。我建議從閱讀Aeson的檔案開始,它是主要的Haskell JSON包。如果你使用jsonResponse請求型別,那么它會自動將回應轉換為具有FromJSON實體的任何型別。
也許這個關于在Haskell中使用JSON的stackoverflow答案也可以幫助你。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/316917.html
標籤:
