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 :: Client -> String -> q -> IO (Result j)
delete = Method -> Client -> String -> q -> IO (Result j)
forall q j.
(QueryLike q, FromJSON j) =>
Method -> Client -> String -> q -> IO (Result j)
http Method
methodDelete
get :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Result j)
get :: Client -> String -> q -> IO (Result j)
get = Method -> Client -> String -> q -> IO (Result j)
forall q j.
(QueryLike q, FromJSON j) =>
Method -> Client -> String -> q -> IO (Result j)
http Method
methodGet
post :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Result j)
post :: Client -> String -> q -> IO (Result j)
post = Method -> Client -> String -> q -> IO (Result j)
forall q j.
(QueryLike q, FromJSON j) =>
Method -> Client -> String -> q -> IO (Result j)
http Method
methodPost
put :: (QueryLike q, FromJSON j) => Client -> String -> q -> IO (Result j)
put :: Client -> String -> q -> IO (Result j)
put = Method -> Client -> String -> q -> IO (Result j)
forall q j.
(QueryLike q, FromJSON j) =>
Method -> Client -> String -> q -> IO (Result j)
http Method
methodPut
http :: (QueryLike q, FromJSON j) => Method -> Client -> String -> q -> IO (Result j)
http :: Method -> Client -> String -> q -> IO (Result j)
http Method
httpMethod Client
client String
resource q
query = do
Request
request <- Method -> Client -> String -> q -> IO Request
forall q.
QueryLike q =>
Method -> Client -> String -> q -> IO Request
buildRequest Method
httpMethod Client
client String
resource q
query
Response ByteString
response <- Client -> Request -> IO (Response ByteString)
performRequest Client
client Request
request
Result j -> IO (Result j)
forall (m :: * -> *) a. Monad m => a -> m a
return (Response ByteString -> Result j
forall j. FromJSON j => Response ByteString -> Result j
handleResponse Response ByteString
response)
buildRequest :: QueryLike q => Method -> Client -> String -> q -> IO Request
buildRequest :: Method -> Client -> String -> q -> IO Request
buildRequest Method
httpMethod Client
client String
resource q
query = do
Request
request <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
parseRequest (Client -> String -> q -> String
forall q. QueryLike q => Client -> String -> q -> String
buildUrl Client
client String
resource q
query)
Request -> IO Request
forall (m :: * -> *) a. Monad m => a -> m a
return Request
request
{ method :: Method
method = Method
httpMethod
}
buildUrl :: QueryLike q => Client -> String -> q -> String
buildUrl :: Client -> String -> q -> String
buildUrl Client
client String
resource q
query = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ String
"https://www.strava.com/"
, String
resource
, Method -> String
unpack (Bool -> Query -> Method
renderQuery Bool
True (Client -> Query
buildQuery Client
client Query -> Query -> Query
forall a. [a] -> [a] -> [a]
++ q -> Query
forall a. QueryLike a => a -> Query
toQuery q
query))
]
buildQuery :: Client -> Query
buildQuery :: Client -> Query
buildQuery Client
client = [(String, String)] -> Query
forall a. QueryLike a => a -> Query
toQuery
[ (String
"access_token", Client -> String
client_accessToken Client
client)
]
performRequest :: Client -> Request -> IO (Response ByteString)
performRequest :: Client -> Request -> IO (Response ByteString)
performRequest Client
client Request
request = (Client -> Request -> IO (Response ByteString)
client_requester Client
client) Request
request
handleResponse :: FromJSON j => Response ByteString -> Result j
handleResponse :: Response ByteString -> Result j
handleResponse Response ByteString
response = case Response ByteString -> Either String j
forall j. FromJSON j => Response ByteString -> Either String j
decodeValue Response ByteString
response of
Left String
message -> (Response ByteString, String) -> Result j
forall a b. a -> Either a b
Left (Response ByteString
response, String
message)
Right j
value -> j -> Result j
forall a b. b -> Either a b
Right j
value
decodeValue :: FromJSON j => Response ByteString -> Either String j
decodeValue :: Response ByteString -> Either String j
decodeValue Response ByteString
response = ByteString -> Either String j
forall a. FromJSON a => ByteString -> Either String a
eitherDecode (Response ByteString -> ByteString
forall body. Response body -> body
responseBody Response ByteString
response)