Как правильно выполнять операции REST PUT Idempotent при использовании версий - PullRequest
0 голосов
/ 24 апреля 2018

Я знаю, что операции REST PUT должны быть идемпотентными.И я знаю, что они предназначены для поддержки управления версиями (поэтому, если я попытаюсь обновить объект, на котором у меня была старая версия 4, но новая версия - 5, я должен получить ответ о конфликте 409. Но как правильно обращаться с идемпотентностью?и управление версиями?

Допустим, у моих объектов есть версия и одно поле данных (например, «имя»). Если мой текущий объект находится в / objects / 1 и имел версию 1 с именем «Алиса», и я хотел обновить его до версии 2 с именем «bob», я, вероятно, отправил бы PUT с версией 2 и именем «bob». Но, поскольку он идемпотентен, я должен иметь возможность отправлять его повторно и иметь эффектто же самое, что и один вызов. Последующие вызовы обычно не проходят проверку версий, за исключением того, что их другие данные будут соответствовать тому, что находится на сервере, и могут быть обнаружены как (или, по крайней мере, предполагается, что) повторяющиеся запросы.

Должны ли ответы на все повторяющиеся вызовы быть одинаковыми (например, 200 OK или 204 Нет содержимого)? Или код ответа должен указывать, является ли вызов действительнымли внес изменения (и увеличил версию), или был ли он обнаружен как повторный вызов (что в противном случае было бы помечено как конфликт 409, за исключением того факта, что данные в PUT были такими же, как те, что уже были там)?И если это должно указывать на разницу, каков подходящий способ отличить их в ответе?

И, я полагаю, мне следует также спросить, обычно ли REST-управление версиями выполняется в объекте (например, с полем версииобъект REST), или это делается в протоколе REST (например, как поле HTTP, сохраняя объект «чистым»)?

1 Ответ

0 голосов
/ 24 апреля 2018

Должны ли ответы на все повторяющиеся вызовы быть одинаковыми (например, 200 OK или 204 Нет содержимого)?

Да - соответствующая часть спецификации HTTP находится в RFC 7232 . Просмотрите описание If-Match :

Исходный сервер НЕ ДОЛЖЕН выполнять запрошенный метод, если полученное условие If-Match оценивается как ложное; вместо этого сервер происхождения ДОЛЖЕН ответить либо а) кодом состояния 412 (Не выполнено предварительное условие), либо б) одним из кодов состояния 2xx (Успешно), если сервер источника подтвердил, что запрашивается изменение состояния, а окончательное состояние уже отражено в текущем состоянии целевого ресурса (т. е. изменение, запрошенное пользовательским агентом, уже успешно выполнено, но пользовательский агент может не знать об этом, возможно, из-за того, что предыдущий ответ был потерян или совместимое изменение было сделано каким-то другим пользовательский агент). В последнем случае сервер происхождения НЕ ДОЛЖЕН отправлять поле заголовка валидатора в ответе, если только он не может проверить, что запрос является дубликатом непосредственно предшествующего изменения, внесенного тем же пользовательским агентом.

Мое прочтение таково, что серверу не требуется для проверки того, что изменение уже успешно выполнено; но если он выполняет такую ​​проверку и хочет сообщить результат клиенту, это способ сделать это.

Я не вижу причин, по которым такая же логика не будет применима там, где вместо этого можно использовать код состояния 409 Conflict .

Полагаю, мне следует также спросить, выполняется ли обычно управление версиями REST в объекте (например, с помощью поля версии объекта REST) ​​или это выполняется в протоколе REST (например, в виде поля HTTP, сохраняя объект " очистить ")

Не все типы мультимедиа позволяют встраивать метаданные управления версиями в представление ресурса (мы используем тот же PUT для изображений, который мы используем для документов json), поэтому я думаю, что более типично видеть информацию о версиях в метаданных (то есть в заголовках, как описано в RFC 7232 ).

А если оно должно указывать на разницу, как правильно их отличать в ответе?

Не выбрано; Вы можете делать то, что имеет смысл там. В случае «успеха» вам следует отправить «представление о статусе действия» вместе с кодом статуса класса 2xx (см. RFC 7231 6.3.1 ). С 409 Conflict / 412 Precondition Failed - так как эти коды состояния являются членами класса 4xx, вы должны отправить «представление, содержащее объяснение ситуации ошибки и является ли это временным или постоянным условием» (см. RFC 7231 6,5 ).

Может быть полезно просмотреть пример в RFC 7807 Подробная информация о проблеме для HTTP API .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...