module RFC.HTTP.Client
( withAPISession
, HasAPIClient(..)
, BadStatusException
, apiGet
, module Network.Wreq.Session
, module Network.URL
, module Network.HTTP.Types.Status
) where
import Control.Lens
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Network.HTTP.Types.Status hiding (statusCode, statusMessage)
import Network.URL
import Network.Wreq.Lens
import Network.Wreq.Session hiding (withAPISession)
import RFC.JSON (FromJSON, decodeOrDie)
import RFC.Prelude
import RFC.String
withAPISession :: (Session -> IO a) -> IO a
withAPISession = (>>=) $ newSessionControl Nothing tlsManagerSettings
newtype BadStatusException = BadStatusException (Status,URL)
deriving (Show,Eq,Ord,Generic,Typeable)
instance Exception BadStatusException
apiExecute :: (HasAPIClient m, ConvertibleString LazyByteString s) =>
URL -> (Session -> String -> IO (Response LazyByteString)) -> (s -> m a) -> m a
apiExecute rawUrl action converter = do
session <- getAPIClient
response <- liftIO $ action session url
let status = response ^. responseStatus
case status ^. statusCode of
200 -> converter . cs $ response ^. responseBody
_ -> throwM $ badResponseStatus status
where
url = exportURL rawUrl
badResponseStatus status = BadStatusException (status, rawUrl)
apiGet :: (HasAPIClient m, FromJSON a, MonadCatch m, Exception e) => URL -> (e -> m a) -> m a
apiGet url onError =
handle onError $ apiExecute url get decodeOrDie
class (MonadThrow m, MonadIO m) => HasAPIClient m where
getAPIClient :: m Session