Haskell Servant (Клиент) - GET Запрос с заголовками - PullRequest
3 голосов
/ 11 июля 2019

Я пытаюсь повторить этот запрос скручивания с помощью Haskell Servant

curl -v -H 'Accept: application/vnd.twitchtv.v5+json' \
-H 'Client-ID: someapikey' \
-X GET 'https://api.twitch.tv/kraken/clips/top?game=Overwatch&period=week&trending=false&limit=3'

Использование Twitch API. Документы здесь

Это то, что я получил до сих пор

type Game = Text                                                                                                             

type Cursor = Text                                                                                                           

type Language = Text                                                                                                         

type Limit = Int                                                                                                             

type Period = Text                                                                                                           

type Trending = Bool                                                                                                         

type Application = Text                                                                                                      

type ClientID = Text                                                                                                         

type SearchClips = "kraken"                                                                                                  
                 :> "clips"                                                                                                  
                 :> "top"                                                                                                    
                 :> QueryParam "game" Game                                                                                   
                 :> QueryParam "cursor" Cursor                                                                               
                 :> QueryParam "language" Language                                                                           
                 :> QueryParam "limit" Limit                                                                                 
                 :> QueryParam "period" Period                                                                               
                 :> QueryParam "trending" Trending                                                                           
                 :> Header "Accept" Application                                                                              
                 :> Header "Client-ID" ClientID                                                                              
                 :> Get '[JSON] Search   

searchClipAPI :: Proxy SearchClips                                                                                           
searchClipAPI = Proxy                                                                                                        

search                                                                                                                       
  :: Maybe Game                                                                                                              
     -> Maybe Cursor                                                                                                         
     -> Maybe Language                                                                                                       
     -> Maybe Limit                                                                                                          
     -> Maybe Period                                                                                                         
     -> Maybe Trending                                                                                                       
     -> Maybe Application                                                                                                    
     -> Maybe ClientID                                                                                                       
     -> ClientM Search                                                                                                       
search = client searchClipAPI                                                                                                

baseURL :: BaseUrl                                                                                                           
baseURL = BaseUrl Https "api.twitch.tv" 443 ""  

И вот как я запускаю его с http-tls

runGameClipsSearchClient :: Maybe Text -> IO ()                                                                              
runGameClipsSearchClient game = do                                                                                           

  mn <- NT.newTlsManager                                                                                                     

  let args = search                                                                                                          
             game                                                                                                            
             (Just "")                                                                                                       
             (Just "en")                                                                                                     
             (Just 50)                                                                                                       
             (Just "day")                                                                                                    
             (Just False)                                                                                                    
             (Just "application/vnd.twitchtv.v5+json")                                                                       
             (Just "someapikey")                                                                         

      envClient = mkClientEnv mn baseURL                                                                                     

  pPrint =<< runClientM args envClient      

Но я, должно быть, что-то делаю не так, потому что я получаю ошибку «404: не найден» с кодом haskell, но не с запросом curl.

Я подозреваю, что что-то не так с моими заголовками, потому что когда я удаляю

'Accept: application/vnd.twitchtv.v5+json'

из запроса curl, я получаю точно такой же ответ.

1 Ответ

2 голосов
/ 12 июля 2019

Да, servant-client имеет специальную обработку заголовков Accept и Content-Type - если вы попытаетесь включить их с помощью механизма :> Header ..., они удаляются из запроса в функции requestToClientRequest in Servant.Client.Internal.HttpClient.

Я думаю, что самый простой способ заставить заголовок Accept - добавить функцию искажения запроса в ваш Manager. Это определенно уродливый хак, но, похоже, работает. (У меня нет идентификатора клиента Twitch для тестирования, но с этим исправлением я получаю ошибку 400 вместо 404, которую я считаю прогрессом.)

mn <- NT.newTlsManagerWith (NT.tlsManagerSettings { managerModifyRequest = fixAccept })
...
where fixAccept req
    = return $ req { requestHeaders = ("Accept", "application/vnd.twitchtv.v5+json") :
                     filter (("Accept" /=) . fst) (requestHeaders req) }
...