Документ HAL "_links" из Spring Hateoas (с чванством)?

У меня есть служба REST, которую я хочу документировать для моей команды разработчиков.

Итак, я добавил некоторые Links из Spring-Hateoas в API ресурсов и подключил к ним аннотации swagger-springmvc @Api... для документирования всего и создания хорошей ссылки API для моей команды Angular, чтобы иметь возможность понять моя служба 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"
            }
        ]}
       }, ...]}   

Я попытался расширить Link и ResourceSupport, чтобы иметь аннотированную версию, но это привело меня в никуда.

Есть ли способ/инструмент, который я мог бы использовать для создания хорошего документа API, сообщающего, что отношение self заключается в том, чтобы получить контент, а отношение delete - удалить коллекцию?

Мне понравился swagger для его хорошего пользовательского интерфейса, но я не возражаю изменить инструмент документации, если его помощь в том, что документ действительно завершен.

В конечном итоге я мог бы подумать об изменении spring -hateoas для другого генератора ссылок, но я не уверен, что сейчас есть лучший инструмент.

Ответ 1

Swagger-UI как таковой не гипермедиа; или, по крайней мере, ограничено тем, что он может ТОЛЬКО перемещаться с верхнего уровня apis на списки api. Это не сильно изменилось в версии 2.0 спецификации, с заметным добавлением ссылки на внешние документы для внеполосной документации.

Что вам нужно, это гибрид браузера HAL и swagger-ui. Как вы правильно указали, существует семантический разрыв между словом "удалить" и тем, что он означает в контексте ресурса коллекции. HAL использует комбинацию кюри и необязательно документ профиля ALPS, чтобы преодолеть этот пробел. Кюры - это не что иное, как версии взаимосвязанных отношений с именами, чтобы они не сталкивались с другими доменами. Restful Web API - отличный ресурс, чтобы узнать больше об этих идеях и о том, как создавать медиа-типы. spring проект по сохранению данных также имеет отличный пример того, как этого добиться.

  • Один из способов, который, как я думаю, будет работать, - отрегулировать спецификацию swagger для поддержки ориентированного на операции просмотра, а не для перечисления ориентированного вида api, а не действительно возможно в таймфрейме, с которым вы, возможно, работаете.
  • Используйте существующий RFC, например rfc5023, чтобы получить общее представление о том, что означает "редактировать" ресурс.
  • Наконец, если ни одна из стандартных связей ссылок не выражает цель действия, определите собственную семантику конкретного приложения, которая предоставляет документацию для этих связей с конкретными приложениями. Таким образом, клиенты вашего сервиса будут иметь общее понимание этих отношений в контексте вашего приложения.

Ниже приведен пример, демонстрирующий и объединяющий эти подходы.

{"collections":
[{"collectionId":"5370a206b399c65f05a7c59e",
  "name":"default",
  "curies": [
       {
          "name": "sw",
          "href": "http://swagger.io/rels/{rel}",
          "templated": true
       },
       {
          "name": "iana",
          "href": "http://tools.ietf.org/html/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 имеют определенное значение, в этом случае "редактирование" имеет очень специфическое значение, которое может реализовать каждый успокоительный клиент. Это расширенный тип ссылки.
  • Священные отношения ссылок также имеют особое значение, это подразумевает глубокие ссылки href на операции в документации apag swagger.
  • Сопоставленные ссылки - это ссылки на конкретные приложения, о которых только ваше приложение знает.

Я знаю, что это точно не отвечает на ваш вопрос, и инструменты в этом пространстве все еще развиваются. Надеюсь, это поможет.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я являюсь одним из основных сопровождающих springfox, который является интеграционным решением spring, что упрощает предоставление описаний сервиса swagger. Поэтому любая обратная связь о том, как вы хотите, чтобы решить эту проблему, очень приветствуется!