Разделяя волосы с REST: Нарушает ли стандартный JSON REST API принцип HATEOAS?

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

Цитируя страницу REST Wikipedia:

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

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

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

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

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

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

Рассмотрим пример "REST" JSON API:

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

/comments.json? # с параметрами...

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

# 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. Это довольно распространено среди "REST" API.

Однако:

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

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

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

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

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

40
задан Peter O. 1 October 2014 в 23:10
поделиться