module Strive.Internal.HTTP where
import Data.Aeson (FromJSON, eitherDecode)
import Data.ByteString.Char8 (unpack)
import Data.ByteString.Lazy (ByteString)
import Data.Monoid ((<>))
import Network.HTTP.Conduit (Request, Response, checkStatus, httpLbs, method,
parseUrl, responseBody)
import Network.HTTP.Types (Method, Query, QueryLike, methodDelete, methodGet,
methodPost, methodPut, renderQuery, toQuery)
import Strive.Client (Client (client_accessToken, client_httpManager))
delete :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Either String j)
delete = http methodDelete
get :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Either String j)
get = http methodGet
post :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Either String j)
post = http methodPost
put :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Either String j)
put = http methodPut
http :: (QueryLike q, FromJSON j) => Method -> Client -> String -> q -> IO (Either String j)
http httpMethod client resource query = do
request <- buildRequest httpMethod client resource query
response <- performRequest client request
return (decodeValue response)
buildRequest :: QueryLike q => Method -> Client -> String -> q -> IO Request
buildRequest httpMethod client resource query = do
request <- parseUrl (buildUrl client resource query)
return request
{ checkStatus = \ _ _ _ -> Nothing
, method = httpMethod
}
buildUrl :: QueryLike q => Client -> String -> q -> String
buildUrl client resource query = concat
[ "https://www.strava.com/"
, resource
, unpack (renderQuery True (buildQuery client <> toQuery query))
]
buildQuery :: Client -> Query
buildQuery client = toQuery
[ ("access_token", client_accessToken client)
]
performRequest :: Client -> Request -> IO (Response ByteString)
performRequest client request = httpLbs request (client_httpManager client)
decodeValue :: FromJSON j => Response ByteString -> Either String j
decodeValue response = eitherDecode (responseBody response)