Для чего используется HTTP метод PATCH?
Что проверяют
Понимаете ли вы разницу между частичным и полным обновлением ресурса и что из неё следует для идемпотентности и конкурентных правок. Следом обычно спрашивают, чем PATCH отличается от PUT при повторной отправке и в каком формате слать изменения.
Как отвечать
PATCH описан в RFC 5789 и применяет к ресурсу набор изменений. PUT, в отличие от него, заменяет ресурс целиком присланным представлением, поэтому поле, которое вы не передали, по смыслу метода должно пропасть или сброситься.
Главные свойства:
- небезопасный и не обязательно идемпотентный: PUT идемпотентен по спецификации, PATCH нет. Операция «добавить элемент в массив» или «увеличить счётчик» при повторе даст другой результат, поэтому автоматически повторять PATCH без ключа идемпотентности нельзя;
- JSON Merge Patch (RFC 7396,
application/merge-patch+json): шлёте объект только с изменёнными полями,nullудаляет поле, массив заменяется целиком. Самый распространённый вариант; - JSON Patch (RFC 6902,
application/json-patch+json): массив операцийadd,remove,replace,move,copy,test. Позволяет точечно менять элементы массивов и проверять значение перед заменой; - ответ: обычно
200с обновлённым ресурсом или204без тела. Неподдерживаемый формат даёт415, а поддерживаемые сервер может перечислить вAccept-Patch.
На фронтенде PATCH удобен для форм: отправляете только изменённые поля (в react-hook-form их видно через dirtyFields) и не затираете то, что параллельно поменял другой пользователь. Для защиты от гонок передают If-Match с ETag, и сервер отвечает 412, если ресурс уже изменился.
Где спотыкаются
Главным плюсом называют экономию трафика. Реальная причина в другом: PUT со старой копией объекта перезапишет чужие изменения в полях, которых вы не трогали.
Пишут method: 'patch' строчными в fetch. Браузер приводит к верхнему регистру только GET, POST, PUT, DELETE, HEAD и OPTIONS, а patch уйдёт как есть, и сервер может ответить 405.
Забывают про CORS: PATCH не входит в простые методы, поэтому перед ним всегда идёт preflight, и метод должен быть в Access-Control-Allow-Methods на сервере.