В чём разница между PUT и PATCH?

JuniorHTTP #http #rest

Вопрос

Чем отличаются методы PUT и PATCH?

Короткий ответ

PUT заменяет ресурс целиком — клиент должен прислать полное представление объекта. PATCH обновляет только переданные поля, остальные остаются без изменений.

Подробный ответ

  • PUT: сервер ожидает полный объект. Если не передать какое-то поле, оно может быть удалено/сброшено в значение по умолчанию — потому что сервер интерпретирует запрос как "вот новое состояние ресурса целиком".
  • PATCH: сервер применяет частичное изменение — набор инструкций или объект с изменёнными полями. Остальные поля ресурса не трогаются.

По идемпотентности:

  • PUT идемпотентен: повторная отправка одного и того же запроса даёт тот же результат.
  • PATCH в общем случае не обязан быть идемпотентным (например, если тело запроса — это инструкция "увеличить счётчик на 1", повторный вызов изменит результат).

Пример

// PUT — нужно прислать ВСЕ поля пользователя,
// иначе непереданные поля могут быть затёрты
await fetch('/api/users/1', {
  method: 'PUT',
  body: JSON.stringify({ name: 'Alice', age: 30, email: 'a@mail.com' })
})

// PATCH — достаточно прислать только то, что меняется
await fetch('/api/users/1', {
  method: 'PATCH',
  body: JSON.stringify({ age: 31 })
})

Дополнительные вопросы

  • Может ли PATCH быть идемпотентным? В каком случае?
  • Что произойдёт, если отправить PUT без поля email — как разные API на это реагируют?
  • Какой формат тела часто используют для PATCH в строгих REST/JSON API (например, JSON Patch, RFC 6902)?