Люди, разрабатывающие HTTP / 2, были гораздо более многословны в своих представлениях о том, что должен делать HTTP, сохраняя при этом старое значение. Давайте посмотрим, что спецификация проекта HTTP / 2 должна сказать об идемпотентности:
4.2.2. Идемпотентные методы
Метод запроса считается «идемпотентным», если предполагаемое воздействие на сервер нескольких идентичных запросов с помощью этого метода такое же, как влияние для одного такого запроса. Из методов запроса, определенных в этой спецификации, PUT, DELETE и безопасный запрос методы идемпотентны.
Как и определение сейфа, свойство идемпотента применяется только к тому, что было запрошено пользователем; сервер может регистрировать каждый запрос отдельно, сохранять историю контроля версий или реализовывать другие неидемпотентные побочные эффекты для каждого идемпотентного запроса .
Предназначен эффект на сервере для каждого такого запроса пута является обновить ресурс , определенный этим URI . Это именно то, что происходит в вашем случае.
То, что вы решили использовать ресурсы версии, здесь не имеет значения. Если вы не хотите создавать новую версию, когда ничего не изменилось, вам нужно сравнить полезную нагрузку в запросе PUT с самой последней (или иным образом идентифицированной) версией ресурса, и когда ни одно из свойств не изменилось Вы можете не создавать новую версию .
Ваше редактирование:
История будет видна пользователю, вызов несколько раз приведет к множественным версиям
Что касается ресурса, то это не побочный эффект . Ресурс по этому URI не изменяется (те же свойства получают PUT). История - это просто метаданные, так как она, скорее всего, запрашивается другим URI или разными заголовками запроса.
time
свойство обновляется? Я думаю, что это тоже метаданные, даже если они есть в ресурсе.HTTP различает два свойства:
Идемпотентность определяется спецификацией следующим образом:
И безопасность:
Обратите внимание, что безопасность подразумевает идемпотентность: если метод не имеет побочных эффектов, то выполнение его несколько раз приведет к тому же побочному эффекту, что и однократное выполнение, а именно ни к одному.
Это помещает методы в три категории:
GET
,HEAD
,OPTION
,TRACE
PUT
,DELETE
POST
Это не правильно.
PUT
идемпотентен, но не безопасен. Весь смысл вPUT
это иметь побочный эффект, а именно обновление ресурса. То, что означает идемпотентность, заключается в том, что обновление одного и того же ресурса с одним и тем же содержимым несколько раз должно иметь тот же эффект, что и обновление его только один раз.Обратите внимание на последний абзац в разделе о безопасности [выделено мной]:
Хотя в этом предложении говорится и о
GET
безопасности, мы можем предположить, что авторы также намеревались применить те же рассужденияPUT
и идемпотентность. IOW:PUT
должен иметь только один видимый пользователю побочный эффект, а именно обновление названного ресурса. У него могут быть другие побочные эффекты, но пользователь не может нести за них ответственность.Например, тот факт, что
PUT
идемпотентен, означает, что я могу повторить его так часто, как захочу: спецификация гарантирует, что выполнение его несколько раз будет точно таким же, как выполнение его один раз. Совершенно верно создать резерв старых версий как побочный эффект от этих многочисленныхPUT
запросов. Однако, если в результате нескольких повторных попыток ваша база данных заполнится резервом старых версий, это не моя проблема, а ваша.IOW: вам разрешено иметь столько побочных эффектов, сколько вы хотите, но
источник
Вы правы, что у PUT не должно быть никаких побочных эффектов , однако я бы кое-что добавил к этому.
Вы обновляете
person
ресурс, который обозначен какF02E395A235
, поэтому использование PUT является правильным. Теперь в качестве бизнес-правила вы также отслеживаете изменения, которые невидимы для вызывающего объекта (потребителя службы REST). Это не добавит новый элемент вperson
ресурс. Исторический снимок не будет доступен с помощью/person/
конечной точки. Поэтому я считаю, что PUT должен быть вполне приемлемым в этом случае.источник