使用Swagger获取Spring Hateoas中的文档HAL "_links"中的链接?

10

我有一个REST服务,我希望为我的客户开发团队提供文档。

因此,我在我的资源API中添加了一些来自Spring-HateoasLinks,并插入了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以使用其他链接生成器,但我不确定现在是否有更好的工具可用。

1个回答

12

Swagger-UI本身并不支持超媒体感知;或者至少它只能从顶级API导航到API列表。在规范的v2.0中,这一点并没有发生太大变化,但值得注意的是增加了链接到外部文档以提供带外文档。

您需要的是HAL浏览器swagger-ui的混合体。正如您所指出的那样,在集合资源的上下文中,“删除”一词与其含义之间存在语义差距。HAL使用curies和可选的profile文档ALPS组合来弥合这个差距。Curies只是链接关系的命名空间版本,以便它们不会与其他域发生冲突。Restful Web APIs是学习这些思想以及如何设计媒体类型的绝佳资源。spring data rest project也有一个很好的例子,可以帮助您实现这一点。
  • 我认为可行的方法之一是调整swagger specification以支持基于操作而非API列表的视图,但在你可能的工作时间范围内不太可能实现。
  • 使用现有的RFC,如rfc5023,共同理解“编辑”资源的含义。
  • 最后,如果没有标准链接关系表达操作的意图,则定义自己的应用程序特定语义,为这些应用程序特定链接关系提供文档。这样,您的服务的客户端将在您的应用程序上下文中共享对这些关系的理解。

下面是一个演示并结合了这些方法的示例。

{"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合格的链接具有特定含义,在这种情况下,“edit”具有每个restful客户端都可以实现的非常特定的含义。这是一种广义的链接类型。
  • sw合格的链接关系也具有特殊含义,它意味着href深度链接到swagger api文档中的操作。
  • col合格的链接是应用程序特定的链接,只有您的应用程序知道。
我知道这并没有精确回答你的问题,而且这个领域的工具仍在不断发展。希望这可以帮到你。
免责声明:我是springfox核心维护人员之一,它是一个spring集成解决方案,可以轻松提供swagger服务描述。所以,对于您想如何解决这个问题的任何反馈,我们都非常欢迎!

感谢您提供的所有参考资料;我已经知道一些,但也发现了其他的。 您提出的新HAL确实比我的当前版本更完整,但我仍然看不到让swagger发现_links数组内容的方法。 事实上,现在我对Spring生成的HAL非常满意。 我想知道解决方案是否是将通用的_links数组转换为包含预定义可选链接字段的结构体。 从语法上讲,实际上只需要删除[],但在实现方面,这肯定要复杂得多 ;) - JR Utily

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接