Сегодня утром я читал 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, а не для рекомендаций по лучшей практике в реальном мире.