on master help sign in
Documentation
6be78e0Julian K. Arni
servant-client-core/src/Servant/Client/Core.hs+29−16
@@ -1,4 +1,3 @@
1−{-# LANGUAGE AllowAmbiguousTypes #-}
2{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
@@ -17,23 +16,34 @@
17-- querying functions for each endpoint just from the type representing your
16-- querying functions for each endpoint just from the type representing your
18-- API.
17-- API.
19module Servant.Client.Core
18module Servant.Client.Core
20− ( AuthClientData
19+ (
21− , AuthenticateReq(..)
20+ -- * Client generation
22− , clientIn
21+ clientIn
23 , HasClient(..)
22 , HasClient(..)
23+
24+ -- * Authentication
24 , mkAuthenticateReq
25 , mkAuthenticateReq
26+ , AuthenticateReq(..)
27+ , AuthClientData
28+
29+ -- * Generic Client
30+ , ClientLike(..)
31+ , genericMkClientL
32+ , genericMkClientP
25 , ServantError(..)
33 , ServantError(..)
26 , EmptyClient(..)
34 , EmptyClient(..)
27− , RunClient(..)
35+
36+ -- * Request
28 , Request(..)
37 , Request(..)
29 , defaultRequest
38 , defaultRequest
30− , Response(..)
31 , RequestBody(..)
39 , RequestBody(..)
40+
41+ -- * Response
42+ , Response(..)
43+ , RunClient(..)
32 , module Servant.Client.Core.Internal.BaseUrl
44 , module Servant.Client.Core.Internal.BaseUrl
33− , ClientLike(..)
45+
34− , genericMkClientL
35− , genericMkClientP
36− -- * Writing instances
46+ -- * Writing HasClient instances
37 , addHeader
47 , addHeader
38 , appendToQueryString
48 , appendToQueryString
39 , appendToPath
49 , appendToPath
@@ -84,13 +94,13 @@ import Servant.Client.Core.Internal.BaseUrl (BaseUrl (..),
84 showBaseUrl)
94 showBaseUrl)
85import Servant.Client.Core.Internal.BasicAuth
95import Servant.Client.Core.Internal.BasicAuth
86import Servant.Client.Core.Internal.Class
96import Servant.Client.Core.Internal.Class
87−import Servant.Client.Core.Internal.Request
88import Servant.Client.Core.Internal.Generic
97import Servant.Client.Core.Internal.Generic
98+import Servant.Client.Core.Internal.Request
89
99
90-- * Accessing APIs as a Client
100-- * Accessing APIs as a Client
91
101
92−-- | 'client' allows you to produce operations to query an API from a client within
102+-- | 'clientIn' allows you to produce operations to query an API from a client
93−-- a given monadic context `m`
103+-- within a 'RunClient' monad.
94--
104--
95-- > type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
105-- > type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
96-- > :<|> "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book -- POST /books
106-- > :<|> "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book -- POST /books
@@ -108,9 +118,12 @@ clientIn :: HasClient m api => Proxy api -> Proxy m -> Client m api
108clientIn p pm = clientWithRoute pm p defaultRequest
118clientIn p pm = clientWithRoute pm p defaultRequest
109
119
110
120
111−-- | This class lets us define how each API combinator
121+-- | This class lets us define how each API combinator influences the creation
112−-- influences the creation of an HTTP request. It's mostly
122+-- of an HTTP request.
113−-- an internal class, you can just use 'client'.
123+--
124+-- Unless you are writing a new backend for @servant-client-core@ or new
125+-- combinators that you want to support client-generation, you can ignore this
126+-- class.
114class RunClient m => HasClient m api where
127class RunClient m => HasClient m api where
115 type Client (m :: * -> *) (api :: *) :: *
128 type Client (m :: * -> *) (api :: *) :: *
116 clientWithRoute :: Proxy m -> Proxy api -> Request -> Client m api
129 clientWithRoute :: Proxy m -> Proxy api -> Request -> Client m api
servant-client-core/src/Servant/Client/Core/Internal/Class.hs+1−1
@@ -3,7 +3,7 @@
3{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE TypeFamilies #-}
4{-# LANGUAGE TypeFamilies #-}
5{-# LANGUAGE OverloadedStrings #-}
5{-# LANGUAGE OverloadedStrings #-}
6−{-| Types for possible backends to run client-side `Request` queries -}
6+-- | Types for possible backends to run client-side `Request` queries
7module Servant.Client.Core.Internal.Class where
7module Servant.Client.Core.Internal.Class where
8
8
9import Control.Monad (unless)
9import Control.Monad (unless)
servant-client-core/src/Servant/Client/Core/Internal/Request.hs+2
@@ -28,6 +28,8 @@ import Web.HttpApiData (ToHttpApiData, toEncodedUrlPiece,
28 toHeader)
28 toHeader)
29
29
30-- | A type representing possible errors in a request
30-- | A type representing possible errors in a request
31+--
32+-- Note that this type substially change in 0.12
31data ServantError =
33data ServantError =
32 -- | The server returned an error response
34 -- | The server returned an error response
33 FailureResponse Response
35 FailureResponse Response
servant-client/src/Servant/Client.hs+7−4
@@ -1,10 +1,13 @@
1+-- | This module provides 'client' which can automatically generate
2+-- querying functions for each endpoint just from the type representing your
3+-- API.
1module Servant.Client
4module Servant.Client
2− ( ClientEnv(..)
5+ ( client
3 , ClientM
6 , ClientM
4 , runClientM
7 , runClientM
5− , client
8+ , ClientEnv(..)
6− , module X
9+ , module Servant.Client.Core
7 ) where
10 ) where
8
11
9import Servant.Client.Internal.HttpClient
12import Servant.Client.Internal.HttpClient
10−import Servant.Client.Core as X
13+import Servant.Client.Core
servant-client/src/Servant/Client/Internal/HttpClient.hs+19−6
@@ -41,23 +41,36 @@ import Servant.Client.Core
41
41
42import qualified Network.HTTP.Client as Client
42import qualified Network.HTTP.Client as Client
43
43
44+-- | The environment in which a request is run.
44data ClientEnv
45data ClientEnv
45 = ClientEnv
46 = ClientEnv
46 { manager :: Client.Manager
47 { manager :: Client.Manager
47 , baseUrl :: BaseUrl
48 , baseUrl :: BaseUrl
48 }
49 }
49
50
51+-- | Generates a set of client functions for an API.
52+--
53+-- Example:
54+--
55+-- > type API = Capture "no" Int :> Get '[JSON] Int
56+-- > :<|> Get '[JSON] [Bool]
57+-- >
58+-- > api :: Proxy API
59+-- > api = Proxy
60+-- >
61+-- > getInt :: Int -> ClientM Int
62+-- > getBools :: ClientM [Bool]
63+-- > getInt :<|> getBools = client api
50client :: HasClient ClientM api => Proxy api -> Client ClientM api
64client :: HasClient ClientM api => Proxy api -> Client ClientM api
51client api = api `clientIn` (Proxy :: Proxy ClientM)
65client api = api `clientIn` (Proxy :: Proxy ClientM)
52
66
53-- | @ClientM@ is the monad in which client functions run. Contains the
67-- | @ClientM@ is the monad in which client functions run. Contains the
54-- 'Manager' and 'BaseUrl' used for requests in the reader environment.
68-- 'Manager' and 'BaseUrl' used for requests in the reader environment.
69+newtype ClientM a = ClientM
55−newtype ClientM a = ClientM { runClientM' :: ReaderT ClientEnv (ExceptT ServantError IO) a }
70+ { runClientM' :: ReaderT ClientEnv (ExceptT ServantError IO) a }
56− deriving ( Functor, Applicative, Monad, MonadIO, Generic
71+ deriving ( Functor, Applicative, Monad, MonadIO, Generic
57− , MonadReader ClientEnv
58− , MonadError ServantError
72+ , MonadReader ClientEnv, MonadError ServantError, MonadThrow
59− , MonadThrow, MonadCatch
73+ , MonadCatch)
60− )
61
74
62instance MonadBase IO ClientM where
75instance MonadBase IO ClientM where
63 liftBase = ClientM . liftBase
76 liftBase = ClientM . liftBase