Search code examples
haskellservant

Generating end-point descriptions in Servant


Servant provides a way to generate documentation from the API definition. However, I see no way of (informally) documenting the functionality of each end-point. For the example used in the link above, the generated documentation contains:

## Welcome

This is our super webservice's API.

Enjoy!

## GET /hello

#### GET Parameters:

- name
     - **Values**: *Alp, John Doe, ...*
     - **Description**: Name of the person to say hello to.


#### Response:

In the example above, what I miss is a way of documenting what the GET /hello end-point does, this is, I would like to have a way to augmenting the API docs with an informal description of each end-point.

## Welcome

This is our super webservice's API.

Enjoy!

## GET /hello

Send a hello message to the given user. /<-- My description.../

#### GET Parameters:

- name
     - **Values**: *Alp, John Doe, ...*
     - **Description**: Name of the person to say hello to.


#### Response:

My guess is that this will require tagging the different end-points to identify them uniquely, something that as far as I know Servant does not support. However, I'm wondering how to solve this problem with what is available as of now.


Solution

  • I believe what you are looking for can be found in the Servant.Docs module of servant-docs (here).

    If you use the docsWith function, you can supply an ExtraInfo object for the api you are documenting:

    docsWith :: HasDocs api => DocOptions -> [DocIntro] -> ExtraInfo api -> Proxy api -> API
    

    I believe that the point of docsWith is to allow you to supply extra endpoint documentation, as you are asking. There is a Monoid instance for ExtraInfo, so it looks like you can build separate ExtraInfo objects for each endpoint in your api, then mappend them together, and pass this to docsWith.

    To build ExtraInfo, use the extraInfo function:

    extraInfo :: (IsIn endpoint api, HasLink endpoint, HasDocs endpoint) => Proxy endpoint -> Action -> ExtraInfo api 
    

    The documentation (linked to above) has an example of how one would go about using the extraInfo function.