10

我有一个 REST 服务,我想为我的客户开发团队记录。

因此,我在我的资源 API 中添加了一些Linksfrom Spring-Hateoas,并插入swagger-springmvc @Api...注释以记录所有内容,并为我的 Angular 团队提供良好的 API 参考,以便能够理解我的 REST 服务。

问题是swagger无法发现哪些链接是可能的,只是给我一大堆Links而不说它们可能的值。

这是一个(简单的)示例。Swagger 检测到:

Model Schema
CollectionListResource {
    collections (array[CollectionResource]): All available collections,
    links (array[Link]): Relations for next actions
}
CollectionResource {
    collectionId (string): Collection Unique Id,
    name (string): Human readable collection name,
    links (array[Link]): Relations for next actions
}
Link {
    rel (string, optional),
    templated (boolean, optional),
    href (string, optional)
} 

我实际上在 HAL 中得到:

 {"collections":
    [{"collectionId":"5370a206b399c65f05a7c59e",
      "name":"default",
       "_links":{ [
           "self":{
              "href":"http://localhost:9080/collections/5370a206b399c65f05a7c59e"
            },

           "delete":{
              "href":"http://localhost:9080/collections/5370a206b399c65f05a7c59e"
            }
        ]}
       }, ...]}   

我试图扩展它们LinkResourceSupport为其添加注释版本,但这导致我无处可去。

有没有一种方法/工具可以用来生成一个好的 API 文档,告诉self关系是获取内容,delete关系是删除集合?

我喜欢 swagger 的良好 UI,但如果它有助于使文档真正完整,我不介意更改我的文档工具。

我最终可以考虑将 spring-hateoas 更改为另一个链接生成器,但我不确定现在是否有更好的工具可用。

4

1 回答 1

12

Swagger-UI 本身不是超媒体感知的;或者至少它的局限性在于它只能从顶级 api 导航到 api 列表。这在规范的 v2.0 中也没有太大变化,显着增加了对带外文档的外部文档的链接。

您需要的是HAL 浏览器swagger-ui的混合体。正如您正确指出的那样,“删除”一词与其在集合资源上下文中的含义之间存在语义差距。HAL 使用居里和可选配置文件ALPS的组合来弥补这一差距。居里只是链接关系的命名空间版本,因此它们不会与其他域发生冲突。Restful Web API是了解这些想法以及如何设计媒体类型的绝佳资源。spring data rest 项目也有一个很好的例子来说明如何实现这一点。

  • 我认为可行的方法之一是调整swagger 规范以支持面向操作的视图而不是面向 api 列表的视图,这在您可能使用的时间范围内实际上是不可能的。
  • 使用诸如rfc5023之类的现有 RFC来共同理解“编辑”资源的含义。
  • 最后,如果没有标准链接关系表达动作的意图,定义您自己的应用程序特定语义,为这些应用程序特定链接关系提供文档。这样,您的服务客户将在您的应用程序上下文中对这些关系有共同的理解。

下面是一个演示和组合这些方法的示例。

{"collections":
[{"collectionId":"5370a206b399c65f05a7c59e",
  "name":"default",
  "curies": [
       {
          "name": "sw",
          "href": "http://swagger.io/rels/{rel}",
          "templated": true
       },
       {
          "name": "iana",
          "href": "https://www.rfc-editor.org/rfc/rfc5023",
          "templated": false
       },
       {
          "name": "col",
          "href": "http://localhost:9080/collections/{rel}",
          "templated": false
       }
   ],
   "_links":{ [
        "self":{
          "href":"http://localhost:9080/collections/5370a206b399c65f05a7c59e"
        },
        "sw:operation":{
          "href":"http://localhost:9080/api-docs/collections#delete"
        },
        "sw:operation":{
          "href":"http://localhost:9080/api-docs/collections#search"
        },
        "sw:operation":{
          "href":"http://localhost:9080/api-docs/collections#update"
        },
        "iana:edit":{
          "href":"http://localhost:9080/collections/5370a206b399c65f05a7c59e"
        },
        "col:delete": {
          "href":"http://localhost:9080/collections/5370a206b399c65f05a7c59e"
        }
    ]}
   }, ...]} 

因此,从最通用到最具体,解决方案(按此顺序)是

  • iana 限定链接具有特定含义,在这种情况下,“编辑”具有非常特定的含义,每个 restful 客户端都可以实现。这是一个通用的链接类型。
  • sw 限定的链接关系也有特殊的含义,它暗示了 swagger api 文档中操作的 href 深层链接。
  • col 限定链接是只有您的应用程序知道的应用程序特定链接。

我知道这并不能准确回答您的问题,并且该领域的工具仍在不断发展。希望这可以帮助。

免责声明:我是springfox的核心维护者之一,它是一个 Spring 集成解决方案,可以轻松提供 Swagger 服务描述。因此,非常欢迎您提供任何有关如何解决此问题的反馈!

于 2014-11-17T04:22:27.467 回答