Подтвердить что ты не робот

Разделение волосков с помощью REST: нарушает ли стандартный JSON REST API HATEOAS?

Сегодня утром я читал REST, и я наткнулся на принцип HATEOAS ( "гипермедиа как двигатель состояния приложения" ).

Цитирование страницы REST Wikipedia:

Клиенты делают переходы состояния только посредством действий, которые динамически идентифицируются в гипермедиа сервером (например, гиперссылками в гипертексте). За исключением простых фиксированных точек входа в приложение, клиент не предполагает, что какие-либо конкретные действия будут доступны для любых конкретных ресурсов, кроме тех, которые описаны в представлениях, ранее полученных с сервера.

И Блог Роя Филдинга:

... если движок состояния приложения (и, следовательно, API) не управляется гипертекстом, тогда он не может быть RESTful и не может быть REST API. Период.

Я читал это как: клиент может запрашивать только изменения состояния на основе действий, сделанных из тела ответа от сервера (гипертекста).

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

Когда ресурс представлен другими способами - например, JSON, XML, YAML и т.д. Это не так очевидно.

Возьмем пример API JSON REST:

Я создаю новый ресурс (например, новый комментарий), отправив запрос POST на

/comments.json? # with params...

Сервер отвечает:

# Headers
HTTP/1.1 201 Created 
Location: http://example.com/comments/3
Content-Type: application/json; charset=utf-8
... Etc.

# Body
{"id":3,"name":"Bodacious","body":"An awesome comment","post_id":"1"}

Я знаю, что теперь я могу получить доступ к этому комментарию в URI, возвращенном в заголовке: http://example.com/comments/3.json

Когда я нахожусь http://example.com/comments/3.json, я вижу:

{"id":3,"name":"Bodacious","body":"An awesome comment","post_id":"1"}

Предположим, что документация по API говорит мне, что я могу удалить этот комментарий, отправив запрос DELETE в тот же URI. Это довольно распространено среди API REST.

Однако:

Ответ с сервера GET http://example.com/comments/3.json не говорит мне ничего о возможности удалить комментарий, отправив запрос DELETE. Все это показывает мне ресурс.

То, что я также могу УДАЛИТЬ комментарий с тем же URL-адресом, - это то, что клиент знает через внеполосную информацию (документацию) и не обнаруживается и управляется ответом сервера.

Здесь клиент предполагает, что для этого ресурса доступно действие DELETE (и возможные другие), и эта информация ранее не была получена с сервера.

Я неправильно понял HATEOAS, или я прав, говоря, что API, соответствующий вышеприведенному описанию, не будет в строгом смысле быть REST API?

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

4b9b3361

Ответ 1

JSON как тип гипермедиа не определяет идентификатор потока приложения. HTML имеет ссылку и тег формы, которые направляют пользователя через процесс.

Если ваше приложение связано только с PUT, POST, DELETE, GET на ресурсе, ваша документация может легко объяснить это.

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

Вы можете использовать HTML/XHTML, создать свой собственный "bodacious + json" или использовать что-то еще. Здесь представлены различные типы медиа http://www.iana.org/assignments/media-types/index.html

Я использую HAL, и у него довольно активная группа. Вот ссылки на него.

http://www.iana.org/assignments/media-types/application/vnd.hal+json

http://stateless.co/hal_specification.html

В книге "Формирование гиперпространственных API с HTML5 и Node" углубляется гипермедиа и типы медиа. В нем показано, как создать тип мультимедиа для определенной или общей цели в XML или JSON.

Ответ 2

Джон Мур дал в ноябре 2010 года о орехах и болтах написания API RESTful (т.е. поддерживающего HATEOAS) и клиента, В первой части он предлагает, что JSON не является надлежащим типом медиа для REST, поскольку в нем отсутствует общепринятый способ представления ссылок и поддерживаемых методов HTTP. Он утверждает, что хороший ol XHTML на самом деле идеален для этого, поскольку инструменты для его синтаксического анализа (то есть XPath) легко доступны, он поддерживает формы (думают о методах построения ссылок GET и методах PUT, POST и DELETE) и имеет хорошо понятный способ идентифицируя гиперссылки, а также некоторые другие преимущества, которые в основном достигаются благодаря возможности использования API с любым стандартным веб-браузером (упрощает работу для разработчиков, QA и сотрудников службы поддержки).

Аргумент, который я всегда делал перед просмотром его разговоров, заключается в том, что JSON намного ниже потребителя полосы пропускания, чем любой * язык ML, например. XML, HTML, XHTML. Но, используя, по возможности, краткий XHTML, такой как относительные ссылки, а не абсолютные (намеченные, но не столь очевидные в примере, который он использует во время его разговора), и с помощью сжатия gzip этот аргумент теряет много веса.

Я реализую такие усилия, как JSON-Schema и other RFC идет, чтобы попытаться стандартизировать вещи в JSON, но тем временем разговор Мура убедил меня попробовать XHTML.

Ответ 3

Решение RESTful предназначено для использования Разрешающего заголовка для информирования клиента о доступных методах/действиях:

> GET /posts/1/comments/1 HTTP/1.1
> Content-Type: application/json
>
< HTTP/1.1 200 OK
< Allow: HEAD, GET, DELETE
< Content-Type: application/json
<
< {
<  "name": "Bodacious",
<  "body": "An awesome comment",
<  "id":   "1",
<  "uri": "/posts/1/comments/1"
< }

Филдинг-диссертация содержит два типа метаданных: метаданные представления; и метаданных ресурса.

Разрешающий заголовок в HTTP/1.1 функционирует как метаданные ресурсов, поскольку он описывает некоторое свойство ресурса; то есть методы, которые он позволяет.

Полностью используя функции, предоставляемые HTTP, вы устраняете необходимость в любой внеочередной информации и становитесь более RESTful.

HATEOAS в простом HTTP-контексте описывает, как клиент может перемещаться из одного представления в другое, следуя URI, используя GET, в то время как заголовок Allow-message информирует клиента о дополнительных методах, поддерживаемых ресурсом, сгенерированным представлением.

Это аккуратный дизайн; клиент запросил представление и дополнительно получил целую кучу дополнительных метаданных о ресурсе, который позволяет эффективно запрашивать дальнейшие представления.

Я думаю, что цитата, которую вы видите на странице REST в Википедии, несколько вводит в заблуждение в выборе слов и не помогла здесь (N.B. Она улучшилась, так как был задан этот вопрос).

Все HTTP-клиенты должны предположить, что для большинства ресурсов может быть доступен GET-метод. Они делают это, потому что поддержка GET и HEAD - это минимальные требования для сервера HTTP/1.1. Без этого предположения сеть не будет функционировать. Если клиент может предположить, что GET доступен, то почему бы не сделать другие предположения о распространенных методах, таких как DELETE или POST?

REST и HTTP нацелены на то, чтобы использовать возможности делать предположения о базовом наборе методов, чтобы уменьшить общий объем запросов в сети; если запрос преуспевает, нет необходимости в дальнейшей связи; но если запрос завершился неудачно с статусом "405 Method Not Allowed", то клиент немедленно получает запросы, которые могут быть успешными с помощью заголовка Allow-header:

> ANNIHILATE /posts/1/comments/1 HTTP/1.1
> Content-Type: application/json
>
< HTTP/1.1 405 Method Not Allowed
< Allow: HEAD, GET, DELETE
< Content-Type: application/json
<

Если базового набора методов HTTP/1.1 недостаточно, вы можете свободно определять свои собственные. Тем не менее, RESTful будет решать проблемы, используя доступные функции HTTP, прежде чем определять новые методы или помещать метаданные в тело сообщения.

Ответ 4

Полностью доступный API JSON, который не требует каких-либо внеполосных знаний, поскольку вы так выразились:

"То, что я также могу УДАЛИТЬ комментарий с тем же URL-адресом, - это то, что клиент знает через внеполосную информацию (документацию) и не обнаруживается и управляется ответом с сервера."

... вполне возможно. Это просто требует простого стандарта и клиента, который понимает стандарт. Проверьте hm-json и проект hm-json Browser:

https://bitbucket.org/ratfactor/hm-json-browser/

Как вы можете видеть в демо, абсолютно никакой внеполосной документации не требуется - только один URL-адрес точки входа, из которого можно открыть все другие ресурсы и их методы HTTP при просмотре.

Кстати, HAL, упомянутый в ответе на судебный процесс, очень, очень близок к вашим гипотетическим требованиям к HATEOAS. Это отличный стандарт, и у него много интересных идей, таких как встроенные ресурсы, но он не может информировать клиента обо всех доступных HTTP-методах, таких как DELETE для данного ресурса.

Ответ 5

Еще одна твердая (и новая по состоянию на май 2013 года) попытка разрешить HATEOAS для JSON можно найти здесь:

JSON API: http://jsonapi.org/

Ответ 6

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

Тело объекта ответа по определению предоставляет вам состояние ресурса в определенный момент времени. Но один ресурс является лишь одним из многих, который включает приложение. Состояние приложения - это объединенные состояния всех ресурсов, связанных с областью - в любой момент времени - с точки зрения потребителя приложения - человека или машины. Чтобы доставить это "состояние приложения", REST API уровня 3 делает возможным HATEOAS.

Поскольку гипертекст - это то, что большинство людей имеет в виду, ссылаясь на "Hyper'media в HATEOAS", особая сила гипертекста - это способность связываться с другими медиа. Кроме того, поскольку большинство гипертекстов из-за HTTP/HTML имеют тенденцию заставлять многих думать, что гиперссылки возможны только через тег привязки или тег ссылки в теле объекта ответа, но это не так.

Если транспортным протоколом является HTTP, то состояние приложения может и должно передаваться через заголовки. В частности, один или несколько "LINK" HEADERS с атрибутом rel для обеспечения семантики. Ссылка HEADER вместе с заголовком ALLOW - это механизмы HTTP для обмена информацией о следующих возможных переходах состояния и способах их доступа.

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

Когда это будет сделано - "копирование" - многие сталкиваются с проблемами типа контента, потому что тело ответа должно быть задано с помощью MIME/Content-типа, такого как XML или JSON, что означает выяснить, как реализовать механизмы HATEOAS через специальный формат определенного типа контента, например пользовательские теги XML или пары ключ: значение вложенного объекта. Вы можете сделать это, многие делают - например, см. предложение json-api выше, но снова HTTP уже предоставляет механизмы для этого.

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

Надеюсь, это поможет. BTW, если вы хотите получить хороший браузер для API API Google Paw API Browser