A family of combinators for defining webservices APIs and serving them

You can learn about the basics in the tutorial.



The latest version of this document is on GitHub.


  • Merge in (and slightly refactor) servant-generic (by Patrick Chilton) into servant (Servant.API.Generic), servant-client-code (Servant.Client.Generic) and servant-server (Servant.Server.Generic).

  • Deprecate Servant.Utils.Links, use Servant.Links.

  • servant-server Deprecate Servant.Utils.StaticUtils, use Servant.Server.StaticUtils.


Signifacant changes

  • Stream takes a status code argument

    -Stream method        framing ctype a
    +Stream method status framing ctype a

    (#966 #972)

  • ToStreamGenerator definition 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


  • Added NoFraming streaming strategy (#959)

  • servant-client-core Free Client implementation. Useful for testing HasClient instances. (#920)

  • servant-client-core Add hoistClient to HasClient. Just like hoistServer allows us to change the monad in which request handlers of a web application live in, we also have hoistClient for 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 HasClient class, for example:

    type Client m (MyCombinator :> api) = MyValue :> Client m api
    hoistClientMonad pm _ nt cl = hoistClientMonad pm (Proxy :: Proxy api) nt . cl
  • servant Add safeLink' :: (Link -> a) -> ... -> MkLink endpoint a, which allows to create helpers returning something else than Link. (#968)

  • servant-server File serving in polymorphic monad. i.e. Generalised types of serveDirectoryFileServer etc functions in Servant.Utils.StaticFiles (#953)

  • servant-server ReqBody content type check is recoverable. This allows writing APIs like:

          ReqBody '[JSON] Int      :> Post '[PlainText] Int
    :<|>  ReqBody '[PlainText] Int :> Post '[PlainText] Int

    which is useful when handlers are subtly different, for example may do less work. (#937)

  • servant-client Add more constructors to RequestBody, including RequestBodyStream. Note: we are looking for http-library agnostic API, so the might change again soon. Tell us which constructors are useful for you! (#913)

Other changes


(VIM) Regular-expression to link PR numbers: s/\v#(\d+)/[#\1](https:\/\/github.com\/haskell-servant\/servant/pull\/\1)/

  • Support base-compat-0.10


Significant changes

Other changes


Bug fixes

  • Prevent double-escaping in link segments (#835 #878)


Significant changes

  • servant-client servant-client-core Factored out of servant-client all the functionality that was independent of the http-client backend. (#803 #821)

    If you have own combinators, you’ll need to add an additional m argument in HasClient, Client and clientWithRoute:

    -class HasClient api
    -  type Client (api :: *) :: *
    -  clientWithRoute :: Proxy api -> Req -> Client api
    +class HasClient m api
    +  type Client (m :: * -> *) (api :: *) :: *
    +  clientWithRoute :: Proxy m -> Proxy api -> Request -> Client m api

    See https://github.com/haskell-servant/servant-auth/pull/67/commits/f777818e3cc0fa3ed2346baff8328e96d62b1790 for a real world example.

  • servant-server Added hoistServer member to the HasServer class, which is HasServer specific enter. (#804 #824)

    enter isn’t exported from Servant module anymore. You can change enter to hoistServer in a straight forward way. Unwrap natural transformation and add a api type Proxy:

    -server = enter (NT nt) impl
    +server = hoistServer (Proxy :: Proxy MyApi) nt impl

    If you have own combinators, you’ll need to define a new method of HasServer class, for example:

    type ServerT (MyCombinator :> api) m = MyValue -> ServerT api m
    hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt . s

    See https://github.com/haskell-servant/servant-auth/pull/67/commits/8ee3b6315247ac076516213fd7cfcdbfdb583ac9 for a real world example.

  • Add Description and Summary combinators (#767)

    It’s possible to annotate endpoints with free form text. This information is used by e.g. by servant-swagger, see screenshot in https://github.com/phadej/servant-swagger-ui

  • Lower :> and :<|> infix precedence to 4 and 3 respectively (#761)

    This shouldn’t affect you, except if you define your own infix operators for Servant type-level DSL.

Other changes

  • servant-foreign Derive Data for all types (#809)
  • servant-docs Add authentication lenses (#787)
  • servant-docs Generated markdown improvements (#813 #767 #790 #788)
  • Add addLinks to generate all links for unnested APIs. (#851)
  • Allow newest dependencies (#772 #842)
  • Documentation improvements and typo fixes (#757 #771 #775 #790 #791 #806)
  • Development process improvements (#764 #839)


Breaking changes

Other changes

  • Add a type representing an empty API (#753)
  • Add linkURI' and Link accessors (#745 , #717 , #715)
  • Prepare for GHC-8.2 (#722)
  • Add HasLink AuthProtect instance (#720)
  • AllCTRender [] () TypeError (use NoContent) (#671)
  • Documentation improvements and typo fixes (#702 , #709 , #716 , #725 , #727)


Breaking changes

  • Use NT from natural-transformation for Enter (#616)

  • Change to MkLink (Verb ...) = Link (previously URI). To consume Link use its ToHttpApiData instance or linkURI. (#527)

Other changes

  • Add Servant.API.TypeLevel module with type families to work with API types. (#345 , #305)

  • Default JSON content type change to application/json;charset=utf-8. (#263) Related browser bugs: Chromium and Firefox

  • Accept class may accept multiple content-types. MimeUnrender adopted as well. (#613 , #615)


  • Added ‘noHeader’ function for not adding response headers.


  • Added Eq, Show, Read, Generic and Ord instances to IsSecure
  • BACKWARDS INCOMPATIBLE: replace use of ToFromByteString with To/FromHttpApiData for GetHeaders/BuildHeadersTo
  • BACKWARDS INCOMPATIBLE: Moved From/ToFormUrlEncoded classes, which were renamed to From/ToForm to http-api-data


  • Add CaptureAll combinator. Captures all of the remaining segments in a URL.
  • Add Servant.API.TypeLevel module, with frequently used type-level functionaliy.


  • Minor fixes, documentation changes and cabal tweaks



  • Add WithNamedConfig combinator.
  • Add HttpVersion, IsSecure, RemoteHost and Vault combinators
  • Fix safeLink, so Header is not in fact required.
  • Add more instances for (:<|>)
  • Use http-api-data instead of Servant.Common.Text
  • Remove matrix params.
  • Add PlainText String MimeRender and MimeUnrender instances.
  • Add new Verbs combinator, and make all existing and new verb combinators type synonyms of it.
  • Add BasicAuth combinator to support Basic authentication
  • Add generalized authentication support


  • Fix missing cases for Patch in safeLink


  • Allow whitespace after parsing JSON
  • Stricter matching for safeLink for Capture


  • Delete now is like Get, Post, Put, and Patch and returns a response body
  • Multiple content-type/accept support for all the relevant combinators
  • Provide JSON, PlainText, OctetStream and FormUrlEncoded content types out of the box
  • Type-safe link generation to API endpoints
  • Support for the PATCH HTTP method
  • Removed the home-made QuasiQuote for writing API types in a more human-friendly format until we come up with a better design for it
  • Make most if not all of the haddock code examples run through doctest
  • Some general code cleanup
  • Add response headers