servant-client-core
Core functionality and class for client function generation for servant APIs
| LTS Haskell 24.16: | 0.20.3.0@rev:2 |
| Stackage Nightly 2025-10-23: | 0.20.3.0@rev:2 |
| Latest on Hackage: | 0.20.3.0@rev:2 |
servant-client-core-0.20.3.0@sha256:60b38f69b903ed8cc2b68ebf59b1a985149edf8b18c742ae406cefdb975fd6be,4813Module documentation for 0.20.3.0
- Servant
- Servant.Client
- Servant.Client.Core
- Servant.Client.Core.Auth
- Servant.Client.Core.BaseUrl
- Servant.Client.Core.BasicAuth
- Servant.Client.Core.ClientError
- Servant.Client.Core.HasClient
- Servant.Client.Core.MultiVerb
- Servant.Client.Core.Reexport
- Servant.Client.Core.Request
- Servant.Client.Core.Response
- Servant.Client.Core.RunClient
- Servant.Client.Core.ServerSentEvents
- Servant.Client.Free
- Servant.Client.Generic
- Servant.Client.Core
- Servant.Client
servant-client-core

HTTP-client-agnostic client functions for servant APIs.
This library should mainly be of interest to backend- and combinator-writers.
For backend-writers
If you are creating a new backend, you’ll need to:
- Define a
RunClientinstance for your datatype (call itMyMonad) - Define a
ClientLikeinstance. This will look like:
instance ClientLike (MyMonad a) (MyMonad a) where
mkClient = id
- Re-export the module Servant.Client.Core.Reexport so that your end-users can be blissfully unaware of ‘servant-client-core’, and so each backend-package comes closer to the warm hearth of the drop-in-replacement equivalence class.
For combinator-writers
You’ll need to define a new HasClient instance for your combinator. There are
plenty of examples to guide you in the
HasClient module.
Changes
The latest version of this document is on GitHub.
Changelog for servant package contains significant entries for all core packages.
Package versions follow the Package Versioning Policy: in A.B.C, bumps to either A or B represent major versions.
0.20.3.0
-
Server-sent events (SSE) for client-side #1811
Implement Server-sent events (SSE) for the Servant client using a new combinator “ServerSentEvents”. The raw event messages, accumulated events and JSON-processed events can be exposed.
-
Integrate MultiVerb #1766 #1804
Expose MultiVerb, a more ergonomic way of defining endpoints that return many kinds of responses. Read the cookbook https://docs.servant.dev/en/master/cookbook/multiverb/MultiVerb.html
-
Add public re-export of renderCurlBasePath lens #1706
-
Remove GHC <= 8.10.7 from the support window #1778
-
Add Servant.API.Range type #1805
-
Add missing HasLink instance for DeepQuery #1784
-
Add Host API combinator #1800
Adding a Host combinator allows servant users to select APIs according to the Host header provided by clients.
0.20.2
- Full query string helpers #1604
This involves exporting
setQueryStringfrom Servant.Client.Core.Request.
0.20
-
Escape special chars in QueryParams. #1584 #1597
Escape special chars in QueryParam (
:@&=+$) in servant-client. Note that this mean binary data will not work as is, and so reverts the functionality in #1432. -
Handle Cookies correctly for RunStreamingClient #1605 #1606
Makes
performWithStreamingRequesttake into consideration the CookieJar, which it previously didn’t. -
Fix the handling of multiple headers with the same name. #1666
servant-client no longer concatenates the values of response headers with the same name. This fixes an issue with parsing multiple
Set-Cookieheaders.
0.19
Significant changes
- Drop support for GHC < 8.6.
- Support GHC 9.0 (GHC 9.2 should work as well, but isn’t fully tested yet).
- Support Aeson 2 (#1475), which fixes a DOS vulnerability related to hash collisions.
- Add
NamedRoutescombinator, making support for records first-class in Servant (#1388). - Add custom type errors for partially applied combinators (#1289, #1486).
- servant-client / servant-client-core / servant-http-streams: Fix erroneous behavior, where only 2XX status codes would be considered successful, irrelevant of the status parameter specified by the verb combinator. (#1469)
- servant-client / servant-client-core: Fix
Showinstance forServant.Client.Core.Request. - servant-client / servant-client-core: Allow passing arbitrary binary data in Query parameters. (#1432).
Other changes
- Various version bumps.
0.18.3
Significant changes
- Add response header support to UVerb (#1420)
Other changes
- Support GHC-9.0.1.
- Bump
bytestring,hspec,base64-bytestringandQuickCheckdependencies.
0.18.2
Significant changes
- Support
Fragmentcombinator.
0.18.1
Significant changes
- Union verbs
Other changes
- Bump “tested-with” ghc versions
- Loosen bound on base16-bytestring
0.18
Significant changes
- Support for ghc8.8 (#1318, #1326, #1327)
0.17
Significant changes
-
Add NoContentVerb #1028 #1219 #1228
The
NoContentAPI endpoints should now useNoContentVerbcombinator. The API type changes are usually of the kind- :<|> PostNoContent '[JSON] NoContent + :<|> PostNoContenti.e. one doesn’t need to specify the content-type anymore. There is no content.
-
Capturecan beLenient#1155 #1156You can specify a lenient capture as
:<|> "capture-lenient" :> Capture' '[Lenient] "foo" Int :> GETwhich will make the capture always succeed. Handlers will be of the type
Either String CapturedType, whereLeft errrepresents the possible parse failure.
Other changes
-
servant-client servant-client-core servant-http-streams Fix Verb with headers checking content type differently #1200 #1204
For
Verbs with responseHeaders, the implementation didn’t check for the content-type of the response. Now it does. -
servant-client servant-http-streams
HasClientinstance forStreamwithHeaders#1170 #1197 -
servant-client Redact the authorization header in Show and exceptions #1238
0.16
-
Rename
ServantErrortoClientError,ServantErrtoServerError#1131 -
servant-client-core Rearrange modules. No more
Internalmodules, whole API is versioned. #1130 -
servant-client-core
RequestBodyis now= RequestBodyLBS LBS.ByteString | RequestBodyBS BS.ByteString | RequestBodySource (SourceIO LBS.ByteString)i.e. no more replicates
http-clients API. #1117 -
servant-client-core Keep structured exceptions in
ConnectionErrorconstructor ofClientError#1115-| ConnectionError Text +| ConnectionError SomeException -
servant-client-core Preserve failing request in
FailureResponseconstructor ofClientError#1114-FailureResponse Response +-- | The server returned an error response including the +-- failing request. 'requestPath' includes the 'BaseUrl' and the +-- path of the request. +FailureResponse (RequestF () (BaseUrl, BS.ByteString)) Response -
servant-client Fix (implement)
StreamBodyinstance #1110 -
servant-client Update CookieJar with intermediate request/responses (redirects) #1104
0.15
-
Streaming refactoring. #991 #1076 #1077
The streaming functionality (
Servant.API.Stream) is refactored to useservant’s ownSourceIOtype (seeServant.Types.SourceTdocumentation), which replaces bothStreamGeneratorandResultStreamtypes.New conversion type-classes are
ToSourceIOandFromSourceIO(replacingToStreamGeneratorandBuildFromStream). There are instances for conduit, pipes and machines in new packages: servant-conduit servant-pipes and servant-machines respectively.Writing new framing strategies is simpler. Check existing strategies for examples.
This change shouldn’t affect you, if you don’t use streaming endpoints.
-
servant-client Separate streaming client. #1066
We now have two
http-clientbased clients, inServant.ClientandServant.Client.Streaming.Their API is the same, except for
Servant.Clientcannot requestStreamendpoints.Servant.Clientis run by directrunClientM :: ClientM a -> ClientEnv -> IO (Either ServantError a)Servant.Client.Streamingcan requestStreamendpoints.Servant.Client.Streamingis used by CPSisedwithClientM :: ClientM a -> ClientEnv -> (Either ServantError a -> IO b) -> IO b
To access
Streamendpoints useServant.Client.StreamingwithwithClientM; otherwise you can continue usingServant.ClientwithrunClientM. You can use both too,ClientEnvandBaseUrltypes are same for both.Note:
Servant.Client.Streamingdoesn’t stream non-Streamendpoints. Requesting ordinaryVerbendpoints (e.g.Get) will block until the whole response is received.There is
Servant.Client.Streaming.runClientMfunction, but it has restricted type.NFData aconstraint prevents using it withSourceT,Conduitetc. response types.runClientM :: NFData a => ClientM a -> ClientEnv -> IO (Either ServantError a)This change shouldn’t affect you, if you don’t use streaming endpoints.
-
servant-client-core Related to the previous:
streamingResponseis removed fromRunClient. We have a new type-class:class RunClient m => RunStreamingClient m where withStreamingRequest :: Request -> (StreamingResponse -> IO a) -> m a -
servant-client-core Add
NFData (GenResponse a)andNFData ServantErrorinstances. #1076 -
servant-client-core Add
aesonandLift BaseUrlinstances #1037
0.14.1
- Merge in
servant-generic(by Patrick Chilton) intoservant(Servant.API.Generic),servant-client-code(Servant.Client.Generic) andservant-server(Servant.Server.Generic).
0.14
-
Streamtakes a status code argument-Stream method framing ctype a +Stream method status framing ctype a -
ToStreamGeneratordefinition changed, so it’s possible to write an instance for conduits.-class ToStreamGenerator f a where - toStreamGenerator :: f a -> StreamGenerator a +class ToStreamGenerator a b | a -> b where + toStreamGenerator :: a -> StreamGenerator b(#959)
-
Added
NoFramingstreaming strategy (#959) -
servant-client-core Free
Clientimplementation. Useful for testingHasClientinstances. (#920) -
servant-client-core Add
hoistClienttoHasClient. Just likehoistServerallows us to change the monad in which request handlers of a web application live, we also havehoistClientfor changing the monad in which client functions live. Read tutorial section for more information. (#936)iF you have own combinators, you’ll need to define a new method of
HasClientclass, for example:type Client m (MyCombinator :> api) = MyValue :> Client m api hoistClientMonad pm _ nt cl = hoistClientMonad pm (Proxy :: Proxy api) nt . cl
0.13.0.1
- Support
base-compat-0.10
0.13
0.12
- First version. Factored out of
servant-clientall the functionality that was independent of thehttp-clientbackend.