Мне было интересно об этом.
Предположим , у меня есть user
ресурс с id
и name
полей. Если я хочу обновить поле, я мог бы просто сделать запрос PATCH к ресурсу, как это
PATCH /users/42
{"name": "john doe"}
И тогда приложение обновит имя пользователя 42.
Но почему, если я повторю этот запрос, результат будет другим?
Согласно RFC 5789
PATCH не является ни безопасным, ни идемпотентным
rest
api-design
http
web-api
mattecapu
источник
источник
{"name": "bendjamin franklin"}
Ответы:
Запрос PATCH может быть идемпотентным, но это не обязательно. Вот почему он характеризуется как неидемпотентный.
Может ли PATCH быть идемпотентным или нет, сильно зависит от того, как сообщаются требуемые изменения.
Например, если формат патча имеет форму
{change: 'Name' from: 'benjamin franklin' to: 'john doe'}
, то любой запрос PATCH после первого будет иметь другой эффект (ответ об ошибке), чем первый запрос.Другой причиной неидемпотентности может быть то, что применение модификации к чему-то другому, чем исходный ресурс, может сделать ресурс недействительным. Это также будет иметь место, если вы примените изменение несколько раз.
источник
<name>
элемента. Если PATCH добавляет<name>
элемент к ресурсу, который изначально не содержал его, то применение PATCH дважды (или применение его к ресурсу, который уже содержит a<name>
) делает ресурс недействительным, поскольку он внезапно будет содержать два<name>
элемента, что недопустимо за такие ресурсы.Я думаю, что четкий ответ, когда PATCH в не идемпотентном является этот абзац из RFC 5789:
Поскольку RFC указывает, что исправление содержит некоторые «общие изменения» ресурса, мы должны смотреть не только на типичную замену поля. Если ресурс предназначен для счетчика, то patch может запросить его приращение, что явно не идемпотет.
источник
PATCH
Запросы описывают набор операций, которые будут применены к ресурсу. Если вы примените один и тот же набор операций дважды к одному и тому же ресурсу, результат может не совпадать. Это потому, что определение операций зависит от вас. Другими словами, вы должны определить правила объединения .Помните, что
PATCH
запрос может использоваться для исправления ресурсов во многих различных форматах, а не только в формате JSON.Таким образом,
PATCH
запрос может быть идемпотентным, если вы определяете правила слияния как идемпотентные .Идемпотентный пример:
Неидемпотентный пример:
Во втором примере я использовал синтаксис типа «Монго», который я создал для увеличения атрибута. Понятно, что это не идемпотент, так как отправка одного и того же запроса несколько раз приведет к разным результатам каждый раз.
Теперь вы можете задаться вопросом, допустимо ли использование такого составного синтаксиса. Согласно стандартам это:
И вы можете также задаться вопросом, насколько удобно использовать
PATCH
запросы таким образом, и многие считают, что это не так, вот хороший ответ с большим количеством комментариев по данной проблеме.источник