Bootstrapped my haskell client
This commit is contained in:
parent
36cc33f9e9
commit
a775330b4f
12 changed files with 389 additions and 2 deletions
34
haskell/src/SpaceTraders/APIClient/Agent.hs
Normal file
34
haskell/src/SpaceTraders/APIClient/Agent.hs
Normal file
|
@ -0,0 +1,34 @@
|
|||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module SpaceTraders.APIClient.Agent
|
||||
( RegisterMessage(..)
|
||||
, myAgent
|
||||
, register
|
||||
) where
|
||||
|
||||
import Data.Aeson
|
||||
import GHC.Generics
|
||||
import qualified Data.Text as T
|
||||
import Network.HTTP.Simple
|
||||
|
||||
import SpaceTraders.APIClient.Client
|
||||
import SpaceTraders.Model.Agent
|
||||
|
||||
myAgent :: T.Text -> IO (Either APIError Agent)
|
||||
myAgent t = send $ setRequestPath "/v2/my/agent"
|
||||
$ tokenReq t
|
||||
|
||||
data RegisterRequest = RegisterRequest { symbol :: T.Text
|
||||
, faction :: T.Text
|
||||
} deriving (ToJSON, Generic, Show)
|
||||
data RegisterMessage = RegisterMessage { token :: T.Text
|
||||
, agent :: Agent
|
||||
} deriving (FromJSON, Generic, Show)
|
||||
|
||||
register :: T.Text -> T.Text -> IO (Either APIError RegisterMessage)
|
||||
register s f = send $ setRequestPath "/v2/register"
|
||||
$ setRequestMethod "POST"
|
||||
$ setRequestBodyJSON RegisterRequest{symbol = s, faction = f}
|
||||
$ defaultReq
|
69
haskell/src/SpaceTraders/APIClient/Client.hs
Normal file
69
haskell/src/SpaceTraders/APIClient/Client.hs
Normal file
|
@ -0,0 +1,69 @@
|
|||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module SpaceTraders.APIClient.Client
|
||||
( APIError(..)
|
||||
, APIMessage(..)
|
||||
, defaultReq
|
||||
, fromJSONValue
|
||||
, send
|
||||
, tokenReq
|
||||
) where
|
||||
|
||||
import Control.Exception
|
||||
import Control.Monad
|
||||
import Data.Aeson
|
||||
import Data.Aeson.Types
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as T
|
||||
import Network.HTTP.Simple
|
||||
import Network.HTTP.Types.Status
|
||||
|
||||
data APIError = APIError { apiErrorCode :: Int
|
||||
, apiErrorMessage :: T.Text
|
||||
} deriving Show
|
||||
instance Exception APIError
|
||||
instance FromJSON APIError where
|
||||
parseJSON (Object o) = do
|
||||
e <- o .: "error"
|
||||
APIError <$> e .: "code"
|
||||
<*> e .: "message"
|
||||
parseJSON _ = mzero
|
||||
|
||||
data APIMessage = APIMessage { data_ :: Value } deriving (Show)
|
||||
instance FromJSON APIMessage where
|
||||
parseJSON (Object o) = APIMessage <$> o .: "data"
|
||||
parseJSON _ = mzero
|
||||
|
||||
defaultReq :: Request
|
||||
defaultReq = setRequestHost "api.spacetraders.io"
|
||||
$ setRequestPort 443
|
||||
$ setRequestSecure True
|
||||
$ setRequestHeader "Content-Type" ["application/json"]
|
||||
$ defaultRequest
|
||||
|
||||
tokenReq :: T.Text -> Request
|
||||
tokenReq token = setRequestHeader "Authorization" [T.encodeUtf8 $ "Bearer " <> token]
|
||||
$ defaultReq
|
||||
|
||||
fromJSONValue :: FromJSON a => Value -> Either String a
|
||||
fromJSONValue = parseEither parseJSON
|
||||
|
||||
send :: FromJSON a => Request -> IO (Either APIError a)
|
||||
send request = do
|
||||
response <- httpLbs request
|
||||
let status = statusCode $ getResponseStatus response
|
||||
body = getResponseBody response
|
||||
if status >= 200 && status <= 299
|
||||
then case eitherDecode body of
|
||||
Left e -> return $ Left APIError{apiErrorCode = -1000, apiErrorMessage = T.pack $ concat ["Error decoding JSON APIMessage: ", e]}
|
||||
Right r -> case fromJSONValue (data_ r) of
|
||||
Left e -> return $ Left APIError{apiErrorCode = -1001, apiErrorMessage = T.pack $ concat ["Error decoding JSON message contents: ", e]}
|
||||
Right m -> return $ Right m
|
||||
else case eitherDecode body of
|
||||
Left e -> return $ Left APIError{apiErrorCode = -status, apiErrorMessage = T.pack $ concat ["Error decoding JSON APIError: ", e, ". Got HTTP body: ", show body]}
|
||||
Right e -> return $ Left e
|
||||
|
||||
--handleAPIError :: SomeException -> IO (Maybe RegisterMessage)
|
||||
--handleAPIError e = do
|
||||
-- print e
|
||||
-- return Nothing
|
Loading…
Add table
Add a link
Reference in a new issue