Ответ 1
Я изучил эту тему некоторое время, но я не уверен, какие возможные решения используют ppl, а какие нет. Есть только несколько доступных примеров... Поэтому мне понадобится обзор экспертов... (Мои примеры будут в основном в HAL + JSON.)
1).
У меня такое чувство, что отношения связей должны быть только GET, потому что в HTML они предназначены для включения таких вещей, как таблицы стилей. Я думаю, что у другого ppl было такое же чувство, потому что отношения IATA связаны с edit-form
и a create-form
.
-
Итак, первое возможное решение для разыменования ссылок с отношениями формы и, следовательно, загрузка описаний форм для операций записи. Эти описания форм могут содержать фрагменты HTML или схему, которые мы можем использовать для создания форм. Например
Просто упомянем, что вы можете использовать один и тот же подход, отправив те же ссылки в заголовке и отправив raw JSON как тело.
{ "_links": { "edit-form": { "href": "http://example.com/users/1?form=edit", "type": "text/html", "title": "Edit user" } } }
Итак, что, если отношения ссылок не только для чтения?
2.)
Затем мы можем использовать встроенные функции HAL:
-
Если мы отправляем данные, мы можем использовать
type
для описания тела запроса вместо тела ответа. Ofc. в этом случае не должно быть тела ответа, или это решение будет путать.{ "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit": { "href": "http://example.com/users/1", "type": "application/vnd.example.user+json", "title": "Edit user" } } }
Итак, в этом случае клиент будет знать, что
my:edit
означает, что это форма редактирования, и, проверив тип MIME, он будет знать, какой тип формы будет отображаться. -
Альтернативное решение для использования настраиваемого отношения ссылок для этой же цели:
{ "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit-user": { "href": "http://example.com/users/1", "type": "application/json", "title": "Edit user" } } }
Итак, извлекая docs
http://example.com/rels/edit-user
, мы можем найти описание о том, как создать форму для редактирования пользователей, и поэтому мы можем поддерживать связь ссылкиmy:edit-user
в нашем клиенте. Документы могут содержать необязательную форму HTML или какую-либо схему или документ RDF с использованием словарного описания формы и т.д. -
Мы можем следовать тому же подходу с помощью свойства
profile
ссылок. Например:{ "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit": { "href": "http://example.com/users/1", "type": "application/json", "title": "Edit user", "profile": "http://example.com/profiles/user" } } }
Итак, отношение ссылки означает, что это форма редактирования, а
profile
описывает, как сгенерировать форму под URLhttp://example.com/profiles/user
.
3).
Или мы можем расширить HAL с помощью пользовательских свойств.
-
Например dougrain-forms делает следующее:
{ "_forms": { "edit": { "href": "http://example.com/users/1", "headers": { "content-type": "application/json" }, "title": "Edit user", "method": "PUT", "schema": { "required": [ "name" ], "type": "object", "properties": { "name": { "type": "string" } }, "title": "user properties" } } } }
-
Но вы можете использовать любой альтернативный подход, если у нас нет стандарта о HAL и о формах HAL, например, я бы предпочел использовать схему mongoose как решение:
{ "name": "John", "_links": { "curies": [ { "name": "my", "href": "http://example.com/rels/{rel}", "templated": true } ], "my:edit": { "href": "http://example.com/users/1", "type": "application/json", "title": "Edit user", "method": "PUT", "_embedded": { "schema": { "name": "String" } } } } }
4.)
Не используйте связи и простые JSON-форматы, такие как HAL, вместо этого используйте RDF с одним или несколькими словарями. Сложнее использовать RDF, но это прекрасное решение для развязки клиентов из служб REST, тогда как HAL - это просто крупнозернистое решение...
-
Например JSON-LD с Hydra и пользовательским vocab:
{ "@context": [ "http://www.w3.org/ns/hydra/core", "https://example.com/docs#" ], "@id": "https://example.com/users/1", "name": "John", "operation": { "@type": "ReplaceResourceOperation", "title": "Edit user", "method": "PUT", "expects": { "@id": "https://example.com/docs#User", "supportedProperty": { "@type": "SupportedProperty", "title": "name", "property": "https://example.com/docs#User.name", "range": "http://www.w3.org/2001/XMLSchema#string", "required": true } } } }