servant icon indicating copy to clipboard operation
servant copied to clipboard

Change HasDocs instances for Summary and Description

Open adetokunbo opened this issue 6 years ago • 4 comments

  • if a description follows a summary, the summary is used as a title and the lines of description form a body.

  • if a description occurs without a preceding summary, it's first line is used as a title, and the remainder are used as a body.

Fixes #1026

adetokunbo avatar Aug 25 '18 01:08 adetokunbo

@alpmestan just checking in - this is approved, so I assume a maintainer will merge it ?

adetokunbo avatar Oct 29 '18 23:10 adetokunbo

I added the golden docs for servant-docs, @adetokunbo could you rebase, and --accept the test if it fails. Then we'll see the difference, if there's any (ComprehensiveAPI doesn't seem to have both summary and description though, so tests should not break)

phadej avatar Nov 08 '18 16:11 phadej

I've stumbled upon this while trying to create a self describing API. In the end I had to build custom combinators for this purpose so I'm glad it's getting some attention. Thank you for that.

What I'm not sure I agree with is the solution. If I understand it correctly then this will create something like:

## GET /blob/:id

### Retrieve a blob with the specified ID

Description omitted for brevity. 

The problem I have with that structure is that Summary "Retrieve a blob with the specified ID" is turned into a header. This structure doesn't actually allow referencing the section very easily. Especially in presence of multiple notes. One of the hacks that worked nicely for my purposes, before switching to custom combinators, was this:

-- | Retrieve a blob with the specified ID
-- > GET {+api}/blob/{id}
type GetBlob prefix = prefix
    :> Summary "Summary\n\nRetrieve a blob with the specified ID."
    :> Description "Description\n\nDescription omitted for brevity."
    :> "blob"
    :> Capture "id" (Id "blob")
    :> Get '[OctetStream] Blob

Which was rendered into:

## GET /blob/:id

### Summary

Retrieve a blob with the specified ID.

### Description

Description omitted for brevity. 

This worked nicely as it was easy to integrate into wider documentation. The above structure has the advantage that HasDocs instances for Summary and Description are decoupled and there's no need for either complex logic to find the note or overlapping instances. That said, the best format I've found was actually this one:

## GET /blob/:id

Retrieve a blob with the specified ID.

### Description

Description omitted for brevity. 

That required a different rendering function in addition to custom combinators.

trskop avatar Aug 06 '20 20:08 trskop

Hi @adetokunbo! Could you please address the comments by phadej? https://github.com/haskell-servant/servant/pull/1029/files#r229139130 If you wish to continue with this PR, it can be featured in the next major release of Servant!

tchoutri avatar Nov 17 '21 13:11 tchoutri