1

servant我使用越来越大的 Web API 构建了一个 Web API 。

我知道自动为 api 创建文档的两种方法。

首先,有黑线鳕。Haddock 将我的代码变成了超链接的 HTML 页面。整洁的!这特别有用,因为我的 api 端点往往会扩展到多个模块,现在我可以浏览它们并找到相关的类型信息。

但是,haddock并不完全有办法正确显示这些行:

type Public =
       "new"    :> ReqBody '[JSON] UserNewRequest    :> Post '[JSON] UserNewResponse
  :<|> "exists" :> ReqBody '[JSON] UserExistsRequest :> Post '[JSON] Bool
  :<|> "login"  :> ReqBody '[JSON] LoginRequest      :> Post '[JSON] LoginResponse

黑线鳕把它变成了这样的东西:

type Public = ("new" :> (ReqBody '[JSON] UserNewRequest :> Post '[JSON] UserNewResponse)) :<|> (("exists" :> (ReqBody '[JSON] UserExistsRequest :> Post '[JSON] Bool)) :<|> ("login" :> (ReqBody '[JSON] LoginRequest :> Post '[JSON] LoginResponse)))

...甚至添加括号。具有讽刺意味的是,代码中的格式更漂亮,仅仅是因为换行符。

二是有servant-docs。然而,servant-docs相当一致地构建端点的文档,带有很好的钩子来添加例如以 JSON 显示的示例。Servant-docs不旨在提供haskell类型信息——这就是我所追求的。


所以要么,我找到一种方法来haddock以一种漂亮的方式显示长类型,或者我找到一种方法来显示 haskell 类型servant-docs

在这两种情况下,它似乎都不适合他们的设计。我可能完全需要别的东西。


我已经尝试过的haddock

type Public =

  -- create new user
       "new"    :> ReqBody '[JSON] UserNewRequest    :> Post '[JSON] UserNewResponse

  -- check if user exists
  :<|> "exists" :> ReqBody '[JSON] UserExistsRequest :> Post '[JSON] Bool

  -- user login
  :<|> "login"  :> ReqBody '[JSON] LoginRequest      :> Post '[JSON] LoginResponse

它是有效的haskell,但评论被忽略haddock。使用 haddock 标题语法--|-- *导致 haddock 编译错误。

4

1 回答 1

2

type评论中提到了使用每个端点别名。但是,较新servant的有(在https://haskell-servant.readthedocs.io/en/stable/cookbook/generic/Generic.htmlServant.API.Generic阅读更多内容)可以让您以更结构化的方式编写 API:

data Public route = Public

  -- | create new user
   { routeNewUser :: route :- "new"    :> ReqBody '[JSON] UserNewRequest    :> Post '[JSON] UserNewResponse

  -- | check if user exists
  , routeExists   :: route :- "exists" :> ReqBody '[JSON] UserExistsRequest :> Post '[JSON] Bool

  -- | user login
  , routeLogin    :: route :- "login"  :> ReqBody '[JSON] LoginRequest      :> Post '[JSON] LoginResponse
  }

这种方法对嵌套 API 来说有点棘手,但在“线性”API 中它有很多好处。

于 2019-02-26T17:46:14.027 回答