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}

Вы рассмотрели большинство распространенных вариантов, однако рассмотрите возможность использования HTTPPATCH метод. Я успешно использовал его через AJAX на Firefox и Chrome. PATCH Метод определяет набор изменений, которые будут применены к документу, а не заменяет весь документ (через PUT).

(Если вы хотите получить только часть документа, попробуйте указать Range заголовок с GET, Для работы с документами XML или JSON вам потребуется определить что-то кроме байтового диапазона - см. Подробности о единицах измерения диапазона.)

Очевидно, что оба эти решения предполагают наличие готового клиента и сервера - если вы не можете поддерживать API на обоих концах запроса, вы не добьетесь большого успеха ни с одним из них.

Другие вопросы по тегам