module Strive.Internal.HTTP
( delete
, get
, post
, put
, buildRequest
, performRequest
, handleResponse
, decodeValue
) where
import Data.Aeson (FromJSON, eitherDecode)
import Data.ByteString.Char8 (unpack)
import Data.ByteString.Lazy (ByteString)
import Network.HTTP.Client (Request, Response, method, parseRequest,
responseBody)
import Network.HTTP.Types (Method, Query, QueryLike, methodDelete, methodGet,
methodPost, methodPut, renderQuery, toQuery)
import Strive.Aliases (Result)
import Strive.Client (Client (client_accessToken, client_requester))
delete :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Result j)
delete = http methodDelete
get :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Result j)
get = http methodGet
post :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Result j)
post = http methodPost
put :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Result j)
put = http methodPut
http :: (QueryLike q, FromJSON j) => Method -> Client -> String -> q -> IO (Result j)
http httpMethod client resource query = do
request <- buildRequest httpMethod client resource query
response <- performRequest client request
return (handleResponse response)
buildRequest :: QueryLike q => Method -> Client -> String -> q -> IO Request
buildRequest httpMethod client resource query = do
request <- parseRequest (buildUrl client resource query)
return request
{ 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 = (client_requester client) request
handleResponse :: FromJSON j => Response ByteString -> Result j
handleResponse response = case decodeValue response of
Left message -> Left (response, message)
Right value -> Right value
decodeValue :: FromJSON j => Response ByteString -> Either String j
decodeValue response = eitherDecode (responseBody response)