api-builder 0.8.0.0 → 0.9.0.0
raw patch · 3 files changed
+18/−10 lines, 3 filesdep −eitherdep ~transformersPVP ok
version bump matches the API change (PVP)
Dependencies removed: either
Dependency ranges changed: transformers
API changes (from Hackage documentation)
- Network.API.Builder.Builder: _baseURL :: Builder -> Text
- Network.API.Builder.Builder: _customizeRequest :: Builder -> Request -> Request
- Network.API.Builder.Builder: _customizeRoute :: Builder -> Route -> Route
- Network.API.Builder.Builder: _name :: Builder -> Text
- Network.API.Builder.Builder: instance Show Builder
- Network.API.Builder.Error: instance Eq a => Eq (APIError a)
- Network.API.Builder.Error: instance Monoid (APIError a)
- Network.API.Builder.Error: instance Show a => Show (APIError a)
- Network.API.Builder.Examples.StackOverflow: instance Eq Question
- Network.API.Builder.Examples.StackOverflow: instance Eq Questions
- Network.API.Builder.Examples.StackOverflow: instance FromJSON Question
- Network.API.Builder.Examples.StackOverflow: instance FromJSON Questions
- Network.API.Builder.Examples.StackOverflow: instance Receivable Questions
- Network.API.Builder.Examples.StackOverflow: instance Show Question
- Network.API.Builder.Examples.StackOverflow: instance Show Questions
- Network.API.Builder.Examples.StackOverflow: isAnswered :: Question -> Bool
- Network.API.Builder.Examples.StackOverflow: score :: Question -> Int
- Network.API.Builder.Examples.StackOverflow: tags :: Question -> [Text]
- Network.API.Builder.Examples.StackOverflow: title :: Question -> Text
- Network.API.Builder.Query: instance ToQuery Bool
- Network.API.Builder.Query: instance ToQuery Int
- Network.API.Builder.Query: instance ToQuery Integer
- Network.API.Builder.Query: instance ToQuery Text
- Network.API.Builder.Query: instance ToQuery a => ToQuery (Maybe a)
- Network.API.Builder.Query: instance ToQuery a => ToQuery [a]
- Network.API.Builder.Receive: instance (Receivable a, Receivable b) => Receivable (a, b)
- Network.API.Builder.Receive: instance (Receivable a, Receivable b, Receivable c) => Receivable (a, b, c)
- Network.API.Builder.Receive: instance (Receivable a, Receivable b, Receivable c, Receivable d) => Receivable (a, b, c, d)
- Network.API.Builder.Receive: instance (Receivable a, Receivable b, Receivable c, Receivable d, Receivable e) => Receivable (a, b, c, d, e)
- Network.API.Builder.Receive: instance Eq a => Eq (JSONResponse a)
- Network.API.Builder.Receive: instance ErrorReceivable ()
- Network.API.Builder.Receive: instance ErrorReceivable ByteString
- Network.API.Builder.Receive: instance ErrorReceivable Value
- Network.API.Builder.Receive: instance FromJSON a => FromJSON (JSONResponse a)
- Network.API.Builder.Receive: instance FromJSON a => Receivable (JSONResponse a)
- Network.API.Builder.Receive: instance Ord a => Ord (JSONResponse a)
- Network.API.Builder.Receive: instance Read a => Read (JSONResponse a)
- Network.API.Builder.Receive: instance Receivable (Response ByteString)
- Network.API.Builder.Receive: instance Receivable ByteString
- Network.API.Builder.Receive: instance Receivable Value
- Network.API.Builder.Receive: instance Show a => Show (JSONResponse a)
- Network.API.Builder.Receive: unwrapJSON :: JSONResponse a -> a
- Network.API.Builder.Routes: httpMethod :: Route -> Method
- Network.API.Builder.Routes: instance Eq Route
- Network.API.Builder.Routes: instance Read Route
- Network.API.Builder.Routes: instance Show Route
- Network.API.Builder.Routes: urlParams :: Route -> [URLParam]
- Network.API.Builder.Routes: urlPieces :: Route -> [URLPiece]
- Network.API.Builder.Send: instance Sendable ()
- Network.API.Builder.Send: instance Sendable ByteString
- Network.API.Builder.Send: instance Sendable PostQuery
- Network.API.Builder.Send: instance Sendable Value
- Network.API.Builder.Send: instance Show PostQuery
- Network.API.Builder.Send.Multipart: instance Show Multipart
+ Network.API.Builder.API: liftExcept :: Monad m => ExceptT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a -> APIT s e m a
+ Network.API.Builder.Builder: [_baseURL] :: Builder -> Text
+ Network.API.Builder.Builder: [_customizeRequest] :: Builder -> Request -> Request
+ Network.API.Builder.Builder: [_customizeRoute] :: Builder -> Route -> Route
+ Network.API.Builder.Builder: [_name] :: Builder -> Text
+ Network.API.Builder.Builder: instance GHC.Show.Show Network.API.Builder.Builder.Builder
+ Network.API.Builder.Error: instance GHC.Base.Monoid (Network.API.Builder.Error.APIError a)
+ Network.API.Builder.Error: instance GHC.Classes.Eq a => GHC.Classes.Eq (Network.API.Builder.Error.APIError a)
+ Network.API.Builder.Error: instance GHC.Show.Show a => GHC.Show.Show (Network.API.Builder.Error.APIError a)
+ Network.API.Builder.Examples.StackOverflow: [isAnswered] :: Question -> Bool
+ Network.API.Builder.Examples.StackOverflow: [score] :: Question -> Int
+ Network.API.Builder.Examples.StackOverflow: [tags] :: Question -> [Text]
+ Network.API.Builder.Examples.StackOverflow: [title] :: Question -> Text
+ Network.API.Builder.Examples.StackOverflow: instance Data.Aeson.Types.Class.FromJSON Network.API.Builder.Examples.StackOverflow.Question
+ Network.API.Builder.Examples.StackOverflow: instance Data.Aeson.Types.Class.FromJSON Network.API.Builder.Examples.StackOverflow.Questions
+ Network.API.Builder.Examples.StackOverflow: instance GHC.Classes.Eq Network.API.Builder.Examples.StackOverflow.Question
+ Network.API.Builder.Examples.StackOverflow: instance GHC.Classes.Eq Network.API.Builder.Examples.StackOverflow.Questions
+ Network.API.Builder.Examples.StackOverflow: instance GHC.Show.Show Network.API.Builder.Examples.StackOverflow.Question
+ Network.API.Builder.Examples.StackOverflow: instance GHC.Show.Show Network.API.Builder.Examples.StackOverflow.Questions
+ Network.API.Builder.Examples.StackOverflow: instance Network.API.Builder.Receive.Receivable Network.API.Builder.Examples.StackOverflow.Questions
+ Network.API.Builder.Query: instance Network.API.Builder.Query.ToQuery Data.Text.Internal.Text
+ Network.API.Builder.Query: instance Network.API.Builder.Query.ToQuery GHC.Integer.Type.Integer
+ Network.API.Builder.Query: instance Network.API.Builder.Query.ToQuery GHC.Types.Bool
+ Network.API.Builder.Query: instance Network.API.Builder.Query.ToQuery GHC.Types.Int
+ Network.API.Builder.Query: instance Network.API.Builder.Query.ToQuery a => Network.API.Builder.Query.ToQuery (GHC.Base.Maybe a)
+ Network.API.Builder.Query: instance Network.API.Builder.Query.ToQuery a => Network.API.Builder.Query.ToQuery [a]
+ Network.API.Builder.Receive: [unwrapJSON] :: JSONResponse a -> a
+ Network.API.Builder.Receive: instance (Network.API.Builder.Receive.Receivable a, Network.API.Builder.Receive.Receivable b) => Network.API.Builder.Receive.Receivable (a, b)
+ Network.API.Builder.Receive: instance (Network.API.Builder.Receive.Receivable a, Network.API.Builder.Receive.Receivable b, Network.API.Builder.Receive.Receivable c) => Network.API.Builder.Receive.Receivable (a, b, c)
+ Network.API.Builder.Receive: instance (Network.API.Builder.Receive.Receivable a, Network.API.Builder.Receive.Receivable b, Network.API.Builder.Receive.Receivable c, Network.API.Builder.Receive.Receivable d) => Network.API.Builder.Receive.Receivable (a, b, c, d)
+ Network.API.Builder.Receive: instance (Network.API.Builder.Receive.Receivable a, Network.API.Builder.Receive.Receivable b, Network.API.Builder.Receive.Receivable c, Network.API.Builder.Receive.Receivable d, Network.API.Builder.Receive.Receivable e) => Network.API.Builder.Receive.Receivable (a, b, c, d, e)
+ Network.API.Builder.Receive: instance Data.Aeson.Types.Class.FromJSON a => Data.Aeson.Types.Class.FromJSON (Network.API.Builder.Receive.JSONResponse a)
+ Network.API.Builder.Receive: instance Data.Aeson.Types.Class.FromJSON a => Network.API.Builder.Receive.Receivable (Network.API.Builder.Receive.JSONResponse a)
+ Network.API.Builder.Receive: instance GHC.Classes.Eq a => GHC.Classes.Eq (Network.API.Builder.Receive.JSONResponse a)
+ Network.API.Builder.Receive: instance GHC.Classes.Ord a => GHC.Classes.Ord (Network.API.Builder.Receive.JSONResponse a)
+ Network.API.Builder.Receive: instance GHC.Read.Read a => GHC.Read.Read (Network.API.Builder.Receive.JSONResponse a)
+ Network.API.Builder.Receive: instance GHC.Show.Show a => GHC.Show.Show (Network.API.Builder.Receive.JSONResponse a)
+ Network.API.Builder.Receive: instance Network.API.Builder.Receive.ErrorReceivable ()
+ Network.API.Builder.Receive: instance Network.API.Builder.Receive.ErrorReceivable Data.Aeson.Types.Internal.Value
+ Network.API.Builder.Receive: instance Network.API.Builder.Receive.ErrorReceivable Data.ByteString.Lazy.Internal.ByteString
+ Network.API.Builder.Receive: instance Network.API.Builder.Receive.Receivable (Network.HTTP.Client.Types.Response Data.ByteString.Lazy.Internal.ByteString)
+ Network.API.Builder.Receive: instance Network.API.Builder.Receive.Receivable Data.Aeson.Types.Internal.Value
+ Network.API.Builder.Receive: instance Network.API.Builder.Receive.Receivable Data.ByteString.Lazy.Internal.ByteString
+ Network.API.Builder.Routes: [httpMethod] :: Route -> Method
+ Network.API.Builder.Routes: [urlParams] :: Route -> [URLParam]
+ Network.API.Builder.Routes: [urlPieces] :: Route -> [URLPiece]
+ Network.API.Builder.Routes: instance GHC.Classes.Eq Network.API.Builder.Routes.Route
+ Network.API.Builder.Routes: instance GHC.Read.Read Network.API.Builder.Routes.Route
+ Network.API.Builder.Routes: instance GHC.Show.Show Network.API.Builder.Routes.Route
+ Network.API.Builder.Send: instance GHC.Show.Show Network.API.Builder.Send.PostQuery
+ Network.API.Builder.Send: instance Network.API.Builder.Send.Sendable ()
+ Network.API.Builder.Send: instance Network.API.Builder.Send.Sendable Data.Aeson.Types.Internal.Value
+ Network.API.Builder.Send: instance Network.API.Builder.Send.Sendable Data.ByteString.Lazy.Internal.ByteString
+ Network.API.Builder.Send: instance Network.API.Builder.Send.Sendable Network.API.Builder.Send.PostQuery
+ Network.API.Builder.Send.Multipart: instance GHC.Show.Show Network.API.Builder.Send.Multipart.Multipart
- Network.API.Builder.API: liftEither :: Monad m => EitherT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a -> APIT s e m a
+ Network.API.Builder.API: liftEither :: Monad m => ExceptT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a -> APIT s e m a
- Network.API.Builder.API: type APIT s e m a = EitherT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a
+ Network.API.Builder.API: type APIT s e m a = ExceptT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a
Files
api-builder.cabal view
@@ -1,5 +1,5 @@ name: api-builder-version: 0.8.0.0+version: 0.9.0.0 synopsis: Library for easily building REST API wrappers in Haskell license: BSD3 license-file: LICENSE@@ -18,7 +18,7 @@ source-repository this type: git location: git://github.com/intolerable/api-builder.git- tag: v0.8.0.0+ tag: v0.9.0.0 library exposed-modules:@@ -38,7 +38,6 @@ attoparsec >= 0.11 && < 0.13, bifunctors >= 4.0 && < 6.0, bytestring == 0.10.*,- either == 4.*, HTTP == 4000.*, http-client == 0.4.7.* || == 0.4.11.*, http-conduit == 2.*,
src/Network/API/Builder/API.hs view
@@ -10,6 +10,7 @@ , routeResponse , routeRequest -- ** Lifting+ , liftExcept , liftEither , liftManager , liftBuilder@@ -30,7 +31,7 @@ import Control.Exception import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.Trans.Class (lift)-import Control.Monad.Trans.Either+import Control.Monad.Trans.Except import Control.Monad.Trans.Reader import Control.Monad.Trans.State import Data.ByteString.Lazy (ByteString)@@ -43,12 +44,17 @@ -- | Main API transformer type. @s@ is the API's internal state, @e@ is the API's custom error type, -- and @a@ is the result when the API runs.-type APIT s e m a = EitherT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a+type APIT s e m a = ExceptT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a -- | Lifts an action that works on an @API@ to an action that works on an @API@. -- This function is provided solely for future-proofing in the case that more transformers -- need to be stacked on top - it's implemented simply as @id@ for the moment.-liftEither :: Monad m => EitherT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a -> APIT s e m a+liftExcept :: Monad m => ExceptT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a -> APIT s e m a+liftExcept = id++{-# DEPRECATED liftEither "Use liftExcept" #-}+-- | Identical to 'liftExcept', provided for (almost) compatibility.+liftEither :: Monad m => ExceptT (APIError e) (ReaderT Manager (StateT Builder (StateT s m))) a -> APIT s e m a liftEither = id -- | Lifts an action that works on a @Manager@ to one that works on an @API@.@@ -86,7 +92,7 @@ -> APIT s e m a -- ^ the actual @API@ to run -> m (Either (APIError e) a, Builder, s) -- ^ IO action that returns either an error or the result, as well as the final states runAPI b m s api = do- ((res, b'), s') <- runStateT (runStateT (runReaderT (runEitherT api) m) b) s+ ((res, b'), s') <- runStateT (runStateT (runReaderT (runExceptT api) m) b) s return (res, b', s') -- | Runs a @Route@. Infers the type to convert to from the JSON with the @a@ in @API@,@@ -109,10 +115,10 @@ sendRoute s r = do builder <- liftBuilder get manager <- liftManager ask- req <- hoistEither $ send builder r s `eitherOr` InvalidURLError+ req <- ExceptT $ return $ send builder r s `eitherOr` InvalidURLError response <- liftIO $ try $ httpLbs req manager- res <- hoistEither $ first HTTPError response- hoistEither $ receive res+ res <- ExceptT $ return $ first HTTPError response+ ExceptT $ return $ receive res -- | Try to construct a @Request@ from a @Route@ (with the help of the @Builder@). Returns @Nothing@ if -- the URL is invalid or there is another error with the @Route@.
src/Network/API/Builder/Send.hs view
@@ -9,6 +9,8 @@ import qualified Data.ByteString.Char8 as ByteString import qualified Data.Text as Text +-- | Class for types that can be sent with api-builder.+-- Given a 'Builder', a 'Route', and an instance of 'Sendable', we should be able to construct a 'Request' for the API's server. If we can't, 'send' returns 'Nothing' and 'APIT' complains about being unable to send the given data. class Sendable s where send :: Builder -> Route -> s -> Maybe Request @@ -49,6 +51,7 @@ return $ req { requestBody = RequestBodyLBS bs } _ -> Nothing +-- | By default, the '()' instance for 'Sendable' moves the query parameters of the 'Route' into the body of the POST request. Most APIs handle both, but some will complain if they aren't sent in the actual query. If you 'send' 'PostQuery' instead of '()', the query params won't move from the actual query string when constructing the request. data PostQuery = PostQuery deriving (Show)