RESTful дизайн ресурса с бинарными состояниями
У меня есть ресурс, который по сути является простым документом CRUD, который имеет небольшой поворот в том, что его можно "переключить" в "синхронизированное" состояние, где вместо того, чтобы использовать собственные текущие значения, он теперь возвращает значения "родителя". документ, с которым он теперь синхронизирован.
Я пытаюсь найти RESTful способ моделирования этого. Ресурс имеет свойство, которое указывает на это состояние Synchronzied = true/false
и ParentId
свойство, чтобы указать, с каким ресурсом оно синхронизируется.
Один из вариантов - просто позволить изменить это во время PUT
обновлений, но это выглядит как-то неправильно, так как это не часть документа, но в некотором отношении это метаданные о документе. Я также рассмотрел POST /document/{id}/synchronized
запрос, в котором запрашиваемое состояние передается в качестве аргумента.
Ни один не чувствует себя вполне правильным, хотя. Первые чувствуют себя немного неловко, потому что мне кажется, что я анализирую представленные данные только для одного значения, а остальные по существу отбрасываются, если мы синхронизируемся. Во втором случае неправильно создавать вложенный ресурс только для одного свойства.
3 ответа
Одно из решений здесь состоит в том, чтобы иметь два разных типа ресурса - полные документы и ведомые документы - различаемые по типу 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 (см. Другие) к родителю.
В ответ на GET для синхронизированного ресурса вы могли бы рассмотреть возвращение 302/303 с заголовком Location, установленным в родительский ресурс. Но затем разрешите PUT на том же синхронизированном URI заменить перенаправление на переданный объект, который затем будет возвращен в последующих ответах GET. Если вы хотите разрешить клиентам переключать сущность обратно в синхронизированное состояние, вы можете сделать это, поместив в дочерний URI тело запроса, содержащее URI нужного родителя. Вы можете даже найти случайные случаи использования, позволяя клиенту размещать любой 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}
Вы рассмотрели большинство распространенных вариантов, однако рассмотрите возможность использования HTTP
PATCH
метод. Я успешно использовал его через AJAX на Firefox и Chrome. PATCH
Метод определяет набор изменений, которые будут применены к документу, а не заменяет весь документ (через PUT
).
(Если вы хотите получить только часть документа, попробуйте указать Range
заголовок с GET
, Для работы с документами XML или JSON вам потребуется определить что-то кроме байтового диапазона - см. Подробности о единицах измерения диапазона.)
Очевидно, что оба эти решения предполагают наличие готового клиента и сервера - если вы не можете поддерживать API на обоих концах запроса, вы не добьетесь большого успеха ни с одним из них.