Что предлагает HATEOAS для обнаружения и отделения, помимо возможности более или менее свободно изменять структуру URL-адресов?

62

В последнее время я читал о гипермедиа как о механизме состояния приложения (HATEOAS), об ограничении, которое, как утверждается, делает веб-API «действительно RESTful». Это сводится к тому, чтобы в основном включать ссылки в каждый ответ на возможные переходы, которые вы можете сделать из текущего состояния.

Позвольте мне проиллюстрировать, что HATEOAS основан на моем понимании - и, пожалуйста, исправьте меня, если я что-то пропустил.

/
    GET: {
        "_links": {
            "child": [
                { "href": "http://myapi.com/articles", "title": "articles" }
            ]
        }
    }

/articles?contains=HATEOAS
    GET: {
        "_items": [
            { "uri": "http://myapi.com/articles/0", "title": "Why Should I Care About HATEOAS?" },
            { "uri": "http://myapi.com/articles/1", "title": "HATEOAS: Problem or Solution?" }
        ],
        "_links": {
            "self": { "href": "http://myapi.com/articles", "title": "articles" },
            "parent": { "href": "http://myapi.com/", "title": "home" }
        }
    }

    POST: {
        "title": "A New Article",
        "body": "Article body",
        "tags": [ "tag1", "tag2" ]
    }

/articles/0
    GET: {
        "title": "Why Should I Care About HATEOAS?",
        "body": "Blah blah blah"
        "tags": [ "REST", "HATEOAS" ],
        "_links": {
            "self": { "href": "http://myapi.com/articles/0", "title": "article" },
            "parent": { "href": "http://myapi.com/articles", "title": "articles" }
        }
    }

Утверждается, что HATEOAS предоставляет два основных преимущества:

  1. Весь сервис доступен для обнаружения, начиная с корневого URI, документация больше не нужна.

  2. Клиент отделен от сервера, который теперь может свободно изменять структуру URI. Это устраняет необходимость в версиях API.

Но, на мой взгляд, сервис - это намного больше, чем его структура URI. Чтобы использовать его эффективно, вам также необходимо знать:

  • какие параметры запроса вы можете использовать и их возможные значения
  • структура JSON / XML / любых документов, которые нужно отправить в запросах POST / PATCH / etc
  • структура ответа, отправленного сервером
  • возможные ошибки, которые могут возникнуть
  • ...

Исходя из вышеизложенного, HATEOAS решает лишь небольшую часть проблем, связанных с обнаружением и связью. Вам все еще нужно задокументировать вышеупомянутые четыре аспекта, и клиенты по-прежнему будут сильно связаны с сервером из-за них. Чтобы избежать взлома клиентов, вам по-прежнему необходимо версия API.

Единственное преимущество, которое он дает, заключается в том, что вы можете более или менее свободно изменять свою структуру URL (кстати, что случилось с принципом «крутые URI не меняются» ?). Правильно ли мое понимание?

Ботонд Балаш
источник

Ответы:

47

Я думаю, что ваши инстинкты в значительной степени правильны; эти объявленные преимущества на самом деле не так уж и велики, как и для любого нетривиального веб-приложения, клиенты должны заботиться о семантике того, что они делают, а также о синтаксисе.

Но это не значит, что вы не должны заставлять ваше приложение следовать принципам HATEOAS!

Что на самом деле означает HATEOAS ? Это означает структурирование вашего приложения таким образом, чтобы оно в принципе было похоже на веб-сайт и чтобы все операции, которые вы могли бы выполнить, могли быть обнаружены без необходимости загрузки какой-либо сложной схемы. (Сложные схемы WSDL могут охватывать все, но к тому времени, когда они это делают, они уже превысили способность практически каждого программиста когда-либо понимать, не говоря уже о написании! Вы можете рассматривать HATEOAS как реакцию на такую ​​сложность.)

HATEOAS - это не просто богатые ссылки. Это означает использование механизмов ошибок стандарта HTTP, чтобы более точно указать, что пошло не так; Вам не нужно просто отвечать «Ваааа! нет », и вместо этого может предоставить документ с описанием того, что на самом деле было не так, и что клиент может с этим сделать. Это также означает поддержку таких вещей, как запросы OPTIONS (стандартный способ предоставления клиентам возможности выяснить, какие методы HTTP они могут использовать) и согласование типов содержимого, чтобы формат ответа можно было адаптировать к форме, которую могут обрабатывать клиенты. Это означает вставку пояснительного текста(или, что более вероятно, ссылки на него), чтобы клиенты могли посмотреть, как использовать систему в нетривиальных случаях, если они не знают; пояснительный текст может быть читаемым человеком или машиночитаемым (и может быть настолько сложным, насколько вы хотите). Наконец, это означает, что клиенты не синтезируют ссылки (за исключением параметров запроса); клиенты будут использовать ссылку, только если вы сказали им это.

Вы должны подумать о том, чтобы сайт просматривался пользователем (который может читать JSON или XML вместо HTML, что немного странно) с большой памятью для ссылок и энциклопедическим знанием стандартов HTTP, но в остальном не знает, что делать. делать.

И, конечно, вы можете использовать согласование типов контента для обслуживания клиента HTML (5) / JS, который позволит им использовать ваше приложение, если его браузер готов принять это. В конце концов, если ваш RESTful API хорош, что должно быть «тривиально» для реализации поверх него?

Donal Fellows
источник
6

Дело в том, что HATEOAS должен иметь второй уровень, определяющий, что такое RESTful API: стандартизированный тип носителя. Рой Филдинг сам сказал

API-интерфейс REST должен потратить почти все свои описательные усилия на определение типов носителей, используемых для представления ресурсов ".

С помощью стандартизированного типа мультимедиа, который явно определяет переход, и гипертекста, указывающего ресурс друг на друга, вы можете создать граф ресурсов, который может принимать любую форму, не нарушая ни одного клиента. Действительно, как и работа в Интернете: у вас есть ссылка между документом, а документ написан на HTML, который определяет, как следовать по этим ссылкам. <a href>это GET, <form>это GET или POST (и определяет шаблон URL для использования в случае GET), <link type="text/css">это GET ... и т. д. Так браузеры могут перемещаться по произвольной структурированной HTML-странице и в Интернете.

Все, что вы сделали

  • какие параметры запроса вы можете использовать и их возможные значения
  • структура JSON / XML / любых документов, которые нужно отправить в запросах POST / PATCH / etc
  • структура ответа, отправленного сервером
  • возможные ошибки, которые могут возникнуть

Есть вопросы, которые должны быть учтены определением стандартизированного вами типа носителя . Конечно, это намного сложнее, и не то, о чем думает большинство людей, когда они определяют «REST» API. Вы не можете просто взять свои бизнес-сущности и поместить их атрибуты в документ JSON, чтобы получить RESTful API.

Конечно, то, что произошло, так это то, что REST каким-то образом разбавлен и означает «использовать HTTP вместо сложных SOAPy» Просто использовать HTTP и HyperText недостаточно для RESTful, это то, что большинство людей ошибаются.

Не то, чтобы это было необходимо, плохие вещи: REST жертвует производительностью и простотой разработки в обмен на более длительную ремонтопригодность и эволюционность. Это было сделано для интеграции приложений большого предприятия. Небольшой веб-API с жестко закодированной структурой JSON может быть тем, что вам нужно. Только не называйте это REST, это специальный веб-API, не более того. И это не значит, что это отстой, это просто означает, что он не пытается следовать ограничениям REST.

дальнейшее чтение

Надеюсь, это поможет уточнить немного :)

Лоран Бурго-Рой
источник
2

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

Вот пример документа Siren :

{
  "class": [ "order" ],
  "properties": { 
      "orderNumber": 42, 
      "itemCount": 3,
      "status": "pending"
  },
  "entities": [
    {
      "class": [ "info", "customer" ],
      "rel": [ "http://x.io/rels/customer" ], 
      "properties": { 
        "customerId": "pj123",
        "name": "Peter Joseph"
      },
      "links": [
        { "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
      ]
    }
  ],
  "actions": [
    {
      "name": "add-item",
      "title": "Add Item",
      "method": "POST",
      "href": "http://api.x.io/orders/42/items",
      "type": "application/x-www-form-urlencoded",
      "fields": [
        { "name": "orderNumber", "type": "hidden", "value": "42" },
        { "name": "productCode", "type": "text" },
        { "name": "quantity", "type": "number" }
      ]
    }
  ],
  "links": [
    { "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
    { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
    { "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
  ]
}

Как вы можете видеть, в сообщении содержится информация о том, как позвонить actions, а затем, интерпретируя эту информацию, клиент становится более устойчивым к изменениям.

Это становится особенно мощным, если rels - это URI, которые можно искать, а не из фиксированного словаря.

mcintyre321
источник
0

Где вы прочитали, что «документация больше не нужна» для сервисов HATEAOS? Как вы говорите, вам все равно нужно документировать семантику ссылок. Тем не менее, с HATEOAS вам не нужно документировать, и, следовательно, навсегда сохранить структуру большинства URI.

HATEOAS позволяет разработчику службы значительно и эффективно изменять и масштабировать реализацию, не изменяя небольшой набор URI, от которых зависит клиент. Легче сохранить небольшое количество точек входа без изменений, чем большой набор. Следовательно, сокращение количества общедоступных точек входа в службу и динамическое предоставление ссылок на подресурсы (HATEOAS) фактически поддерживает «крутые URI не меняются» лучше, чем не-HATEOAS сервисы.

Джонатан Джидди
источник
Одним из мест, где можно прочитать, что «документация больше не нужна», является диссертация Роя Филдинга, который придумал этот термин.
Меритон - забастовка
1
Я просто искал в диссертации Филдинга использование «документации» и не нашел ничего похожего на утверждение «документация больше не нужна». Не могли бы вы указать, где в диссертации Филдинга вы нашли это утверждение?
Джонатан Джидди
0

(HATEOAS), ограничение, которое, как утверждают, делает веб-API "действительно RESTful"

Единственное, что делает его настоящим REST API, - это соблюдение всех ограничений, а не только одного.

Но, на мой взгляд, сервис - это намного больше, чем его структура URI. Чтобы использовать его эффективно, вам также необходимо знать: ...

Вот почему нам нужны другие ограничения, самоописательное сообщение и т. Д.

Чтобы избежать взлома клиентов, вам по-прежнему необходимо версия API.

Независимо от того, как вы пытаетесь, вам нужно будет версия вашего API. В REST-клиенте вам все еще нужно знать, как попасть на страницу, где вы хотите что-то делать, какие ссылки следует использовать и какие свойства вам нужно собрать на основе словаря RDF, описывающего сообщение. Если вам нужно заменить или удалить что-то из этого словаря, это, вероятно, сломает всех ваших клиентов, и вам понадобится новая версия. Поэтому я думаю, что REST - это не то, что вы должны публиковать рано (и выяснить модель, пока вы постоянно меняете API), иначе у вас будет много версий. Для начала вам нужна стабильная модель предметной области ...

inf3rno
источник