RESTful дизайн ресурса с бинарными состояниями
У меня есть ресурс, который по существу является простым CRUD-документом, который имеет небольшой поворот в том, что его можно "переключить" в "синхронизированное" состояние "туда-сюда" вместо использования его собственных текущих значений, теперь оно возвращает значения "родительский" документ, с которым он теперь синхронизирован.
Я пытаюсь найти RESTful способ моделирования этого. Ресурс имеет свойство, которое указывает это состояние Synchronzied = true/false
и ParentId
, чтобы указать, с каким ресурсом он синхронизируется.
Один из вариантов заключается в том, чтобы просто изменить это во время обновлений PUT
, но это кажется некорректным, поскольку это не является частью документа, но в некоторых отношениях это метаданные о документе. Я также рассмотрел запрос POST /document/{id}/synchronized
, в котором запрашиваемое состояние передается в качестве аргумента.
Ничего не получается. Первое ощущение немного неудобно, потому что кажется, что я разбираю представленные данные только для одного значения, остальные существенно отбрасываются, если мы синхронизируем. Во втором случае неправильно создавать вложенный ресурс только для одного свойства.
Ответы
Ответ 1
Одно из решений состоит в том, чтобы иметь два разных типа ресурсов - полные документы и подчиненные документы - отличающиеся по типу MIME. Например, вы можете иметь application/vnd.mysite.document
для полного документа и application/vnd.mysite.documentlink+json
, когда вы просто связываетесь с другим документом.
Чтобы создать подчиненный документ:
PUT /document/1234
Content-Type: application/vnd.mysite.documentlink+json
{"parent": "/document/1"}
Чтобы сделать полный документ:
PUT /document/1234
Content-Type: application/vnd.mysite.document
Hello, I am a document full of stuff.
Затем вы можете отвечать на запросы GET
, возвращая документ или ссылку 303 (см. раздел "Прочее" ) на родителя.
Ответ 2
В ответ на GET на синхронизированный ресурс вы можете подумать о возврате 302/303 с заголовком Location, установленным для родительского ресурса. Но затем разрешите PUT на том же синхронизированном URI, чтобы заменить перенаправление переданным объектом, который затем будет возвращен в последующих ответах GET. Если вы хотите разрешить клиентам переключать объект обратно в синхронизированное состояние, вы можете сделать это, выполнив POST для дочернего URI тела запроса, содержащего URI желаемого родителя. Вы даже можете найти случайные варианты использования, разрешив клиенту POST любой URI, а не только идентификатор небольшого набора известных родителей.
GET /child
200 OK
{foo: bar}
POST /child
{parent: /some/other}
200 OK
GET /child
302/303
Location: /some/other
PUT /child
{foo: baz}
201 Created
GET /child
200 OK
{foo: baz}
Ответ 3
Вы просмотрели большинство общих опций, однако подумайте об использовании метода HTTP
PATCH
. Я успешно использовал его через AJAX как в Firefox, так и в Chrome. Метод PATCH
указывает набор изменений, которые должны применяться к документу, а не замена всего документа (через PUT
).
(Если вы хотите получить только часть документа, подумайте о том, чтобы указать Range
header с GET
. Вам нужно будет определите что-то другое, кроме байтового диапазона, для работы с документами XML или JSON - подробнее см. единицы измерения диапазона.)
Очевидно, что оба этих решения предполагают, что клиент и сервер готовы - если вы не можете поддерживать API на обоих концах запроса, у вас тоже не будет большого успеха.