Reputation: 181
I'm trying to replicate this curl request with 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'
Using Twitch API. Docs here
This is what I've got so far
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 ""
And this is how I 'run' it with 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
But I must be doing something wrong because I get a '404: not found' error with the haskell code but not with the curl request.
I suspect there's something wrong with my headers because when I remove the
'Accept: application/vnd.twitchtv.v5+json'
from the curl request, I get the exact same response.
Upvotes: 5
Views: 1324
Reputation: 50819
Yes, servant-client
has special handling of the Accept
and Content-Type
headers -- if you try to include them using the :> Header ...
mechanism, they are stripped out of the request in the function requestToClientRequest
in Servant.Client.Internal.HttpClient
.
I think the easiest way to force an Accept
header is to add a request mangling function to your Manager
. This is definitely an ugly hack, but it seems to work. (I don't have a Twitch client ID to test, but with this fix, I get a 400 instead of a 404 error, which I believe is progress.)
mn <- NT.newTlsManagerWith (NT.tlsManagerSettings { managerModifyRequest = fixAccept })
...
where fixAccept req
= return $ req { requestHeaders = ("Accept", "application/vnd.twitchtv.v5+json") :
filter (("Accept" /=) . fst) (requestHeaders req) }
Upvotes: 6