HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleservant-docs-0.13.1Haskell2010

Servant.Docs

This module lets you get API docs for free. It lets you generate an API from the type that represents your API using docs:

docs :: HasDocs api => Proxy api -> API

Alternatively, if you wish to add one or more introductions to your documentation, use docsWithIntros:

docsWithIntros :: HasDocs api => [DocIntro] -> Proxy api -> API

You can then call markdown on the API value:

markdown :: API -> String

or define a custom pretty printer:

yourPrettyDocs :: API -> String -- or blaze-html's HTML, or ...

The only thing you'll need to do will be to implement some classes for your captures, get parameters and request or response bodies.

See example/greet.hs for an example.

  • 14 types
  • 4 classes
  • 52 values

HasDocs class and key functions

4 declarations
classclass HasDocs (api :: k) where
#

The class that abstracts away the impact of API combinators on documentation generation.

Methods

Instances29HasDocs, …
valuedocs :: HasDocs api => Proxy api -> API
#

Generate the docs for a given API that implements HasDocs. This is the default way to create documentation.

docs == docsWithOptions defaultDocOptions

Customising generated documentation

Generate documentation in Markdown format for the given API using the specified options.

These options allow you to customise aspects such as:

  • Choose how many content-types for each request body example are shown with requestExamples.

  • Choose how many content-types for each response body example are shown with responseExamples.

For example, to only show the first content-type of each example:

  markdownWith (defRenderingOptions
                  & requestExamples  .~ FirstContentType
                  & responseExamples .~ FirstContentType )
               myAPI
  
datadata RenderingOptions
#

Customise how an API is converted into documentation.

Constructors

Instances1Show
datadata ShowContentTypes
#

How many content-types for each example should be shown?

Constructors

Instances6Bounded, Enum, Eq, Ord, Read, Show

Generating docs with extra information

8 declarations
valuedocsWith
  1. :: HasDocs api
  2. => DocOptions
  3. -> [DocIntro]
  4. -> ExtraInfo api
  5. -> Proxy api
  6. -> API
#

Generate documentation given some extra introductions (in the form of DocInfo) and some extra endpoint documentation (in the form of ExtraInfo.

The extra introductions will be prepended to the top of the documentation, before the specific endpoint documentation. The extra endpoint documentation will be "unioned" with the automatically generated endpoint documentation.

You are expected to build up the ExtraInfo with the Monoid instance and extraInfo.

If you only want to add an introduction, use docsWithIntros.

newtypenewtype ExtraInfo (api :: k)
#

Type of extra information that a user may wish to "union" with their documentation.

These are intended to be built using extraInfo. Multiple ExtraInfo may be combined with the monoid instance.

Instances2Semigroup, Monoid
valueextraInfo
  1. :: (IsIn endpoint api, HasLink endpoint, HasDocs endpoint)
  2. => Proxy endpoint
  3. -> Action
  4. -> ExtraInfo api
#

Create an ExtraInfo that is guaranteed to be within the given API layout.

The safety here is to ensure that you only add custom documentation to an endpoint that actually exists within your API.

extra :: ExtraInfo TestApi
extra =
    extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete)) $
             defAction & headers <>~ [("X-Num-Unicorns", 1)]
                       & notes   <>~ [ DocNote "Title" ["This is some text"]
                                     , DocNote "Second section" ["And some more"]
                                     ]

Classes you need to implement for your types

9 declarations
classclass ToSample a where
#

The class that lets us display a sample input or output in the supported content-types when generating documentation for endpoints that either:

  • expect a request body, or

  • return a non empty response body

Example of an instance:

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Text
import GHC.Generics

data Greet = Greet { _msg :: Text }
  deriving (Generic, Show)

instance FromJSON Greet
instance ToJSON Greet

instance ToSample Greet where
  toSamples _ = singleSample g

    where g = Greet "Hello, haskeller!"

You can also instantiate this class using toSamples instead of toSample: it lets you specify different responses along with some context (as Text) that explains when you're supposed to get the corresponding response.

Methods

Instances22ToSample, …
valuesamples :: [a] -> [(Text, a)]
#

Samples without documentation.

classclass ToParam (t :: k) where
#

The class that helps us automatically get documentation for GET (or other Method) parameters.

Example of an instance:

instance ToParam (QueryParam' mods "capital" Bool) where
  toParam _ =
    DocQueryParam "capital"
                  ["true", "false"]
                  "Get the greeting message in uppercase (true) or not (false). Default is false."

Methods

classclass ToCapture (c :: k) where
#

The class that helps us automatically get documentation for URL captures.

Example of an instance:

instance ToCapture (Capture "name" Text) where
  toCapture _ = DocCapture "name" "name of the person to greet"

Methods

ADTs to represent an API

42 declarations
datadata Endpoint
#

An Endpoint type that holds the path and the method.

Gets used as the key in the API hashmap. Modify defEndpoint or any Endpoint value you want using the path and method lenses to tweak.

Example1 expression
defEndpoint"GET" /
Example1 expression
defEndpoint & path <>~ ["foo"]"GET" /foo
Example1 expression
defEndpoint & path <>~ ["foo"] & method .~ HTTP.methodPost"POST" /foo
Instances6Eq, Ord, Show, Generic, Hashable, Rep
valuedefEndpoint :: Endpoint
#

An Endpoint whose path is `"/"` and whose method is GET

Here's how you can modify it:

Example1 expression
defEndpoint"GET" /
Example1 expression
defEndpoint & path <>~ ["foo"]"GET" /foo
Example1 expression
defEndpoint & path <>~ ["foo"] & method .~ HTTP.methodPost"POST" /foo
datadata API
#

Our API documentation type, a product of top-level information and a good old hashmap from Endpoint to Action

Instances4Eq, Show, Semigroup, Monoid
  • Eq APIDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Show APIDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Semigroup APIDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Monoid APIDefined in servant-docs-0.13.1 · Servant.Docs.Internal
datadata DocQueryParam
#

A type to represent a GET (or other possible Method) parameter from the Query String. Holds its name, the possible values (leave empty if there isn't a finite number of them), and a description of how it influences the output or behavior.

Write a ToParam instance for your GET parameter types

Instances3Eq, Ord, Show
datadata ParamKind
#

Type of GET (or other Method) parameter:

  • Normal corresponds to QueryParam, i.e your usual GET parameter

  • List corresponds to QueryParams, i.e GET parameters with multiple values

  • Flag corresponds to QueryFlag, i.e a value-less GET parameter

Instances3Eq, Ord, Show
  • Eq ParamKindDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Ord ParamKindDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Show ParamKindDefined in servant-docs-0.13.1 · Servant.Docs.Internal
datadata DocNote
#

A type to represent extra notes that may be attached to an Action.

This is intended to be used when writing your own HasDocs instances to add extra sections to your endpoint's documentation.

Instances3Eq, Ord, Show
  • Eq DocNoteDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Ord DocNoteDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Show DocNoteDefined in servant-docs-0.13.1 · Servant.Docs.Internal
datadata DocIntro
#

An introductory paragraph for your documentation. You can pass these to docsWithIntros.

Constructors

Instances3Eq, Ord, Show
  • Eq DocIntroDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Ord DocIntroDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Show DocIntroDefined in servant-docs-0.13.1 · Servant.Docs.Internal
datadata Response
#

A type to represent an HTTP response. Has an Int status, a list of possible MediaTypes, and a list of example ByteString response bodies. Tweak defResponse using the respStatus, respTypes and respBody lenses if you want.

If you want to respond with a non-empty response body, you'll most likely want to write a ToSample instance for the type that'll be represented as encoded data in the response.

Can be tweaked with four lenses.

Example1 expression
defResponseResponse {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}
Example1 expression
defResponse & respStatus .~ 204 & respBody .~ [("If everything goes well", "application/json", "{ \"status\": \"ok\" }")]Response {_respStatus = 204, _respTypes = [], _respBody = [("If everything goes well",application/json,"{ \"status\": \"ok\" }")], _respHeaders = []}
Instances3Eq, Ord, Show
  • Eq ResponseDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Ord ResponseDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Show ResponseDefined in servant-docs-0.13.1 · Servant.Docs.Internal
valuedefResponse :: Response
#

Default response: status code 200, no response body.

Can be tweaked with four lenses.

Example1 expression
defResponseResponse {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}
Example1 expression
defResponse & respStatus .~ 204Response {_respStatus = 204, _respTypes = [], _respBody = [], _respHeaders = []}
datadata Action
#

A datatype that represents everything that can happen at an endpoint, with its lenses:

  • List of captures (captures)

  • List of GET (or other Method) parameters (params)

  • What the request body should look like, if any is requested (rqbody)

  • What the response should be if everything goes well (response)

You can tweak an Action (like the default defAction) with these lenses to transform an action and add some information to it.

Instances3Eq, Ord, Show
  • Eq ActionDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Ord ActionDefined in servant-docs-0.13.1 · Servant.Docs.Internal
  • Show ActionDefined in servant-docs-0.13.1 · Servant.Docs.Internal
valuedefAction :: Action
#

Default Action. Has no captures, no query params, expects no request body (rqbody) and the typical response is defResponse.

Tweakable with lenses.

Example1 expression
defActionAction {_authInfo = [], _captures = [], _headers = [], _params = [], _fragment = Nothing, _notes = [], _mxParams = [], _rqtypes = [], _rqbody = [], _response = Response {_respStatus = 200, _respTypes = [], _respBody = [], _respHeaders = []}}
Example1 expression
defAction & response.respStatus .~ 201Action {_authInfo = [], _captures = [], _headers = [], _params = [], _fragment = Nothing, _notes = [], _mxParams = [], _rqtypes = [], _rqbody = [], _response = Response {_respStatus = 201, _respTypes = [], _respBody = [], _respHeaders = []}}