HTTPQUERY
Русский

PATCH

Применение

Запрос PATCH отправляет набор инструкций, описывающих, как изменить существующий ресурс. В отличие от PUT, который заменяет ресурс целиком, PATCH изменяет только указанные поля или свойства.

Тело запроса содержит patch-документ в формате, понятном серверу. Заголовок Content-Type определяет формат патча. Заголовок Accept-Patch в ответах сервера объявляет поддерживаемые форматы патчей.

Примечание

PATCH не является устаревшим. Метод был стандартизирован в 2010 году и остаётся активной частью семантики HTTP. Путаница возникает потому, что PATCH добавили позже других методов, и некоторые старые фреймворки не поддерживают его нативно.

Примечание

PATCH не даёт гарантий идемпотентности. Двукратное применение одного и того же патча может дать разные результаты (например, двойное добавление элемента в список). Параллельные патчи к одному ресурсу рискуют привести к конфликтам, если не использовать условные запросы (If-Unmodified-Since или If-Match).

Распространённые форматы патчей

JSON Patch выражает изменения в виде упорядоченного массива операций: add, remove, replace, move, copy и test.

Content-Type: application/json-patch+json

[
  {"op":"replace","path":"/email",
   "value":"alice@example.re"},
  {"op":"add","path":"/verified","value":true}
]

JSON Merge Patch использует более простой подход. Patch-документ повторяет структуру целевого ресурса. Поля, присутствующие в патче, перезаписывают существующие значения. Присвоение полю значения null удаляет это поле.

Content-Type: application/merge-patch+json

{"email":"alice@example.re","nickname":null}

Атомарность

Сервер применяет все изменения patch-документа как одну атомарную операцию. Если какая-либо инструкция не выполняется, патч отклоняется целиком, а ресурс остаётся без изменений.

Примечание

Запрос PATCH имеет побочные эффекты и не гарантирует идемпотентности. Два одинаковых патча, применённые последовательно к операции «добавить в список», дают результат, отличный от однократного применения.

JSON Merge Patch

Клиент обновляет адрес электронной почты пользователя 42 в формате JSON Merge Patch. Сервер применяет изменение и возвращает 200 OK с обновлённым ресурсом.

Запрос

PATCH /users/42 HTTP/1.1
Host: api.example.re
Content-Type: application/merge-patch+json
Content-Length: 28

{"email":"alice@example.re"}

Ответ

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 51

{"id":42,"name":"Alice","email":"alice@example.re"}

JSON Patch

Клиент применяет к ресурсу конфигурации две операции: замену флага отладки и добавление нового поля с уровнем логирования. Сервер подтверждает операцию кодом 204 No Content.

Запрос

PATCH /config/app HTTP/1.1
Host: api.example.re
Content-Type: application/json-patch+json
Content-Length: 102

[
  {"op":"replace","path":"/debug","value":false},
  {"op":"add","path":"/logLevel","value":"warn"}
]

Ответ

HTTP/1.1 204 No Content

Условный патч

Условный запрос с If-Unmodified-Since предотвращает изменение ресурса, уже изменённого другим клиентом. Если ресурс был изменён после указанной отметки времени, сервер возвращает 412 Precondition Failed.

Запрос

PATCH /docs/report.json HTTP/1.1
Host: api.example.re
Content-Type: application/merge-patch+json
If-Unmodified-Since: Mon, 01 Jan 2024 12:00:00 GMT
Content-Length: 21

{"status":"reviewed"}

Ответ

HTTP/1.1 412 Precondition Failed
Content-Length: 0

CORS

Межисточниковые запросы PATCH всегда вызывают предварительный запрос CORS. Браузер сначала отправляет запрос OPTIONS, чтобы убедиться, что сервер разрешает PATCH для целевого ресурса.

PATCH против PUT

PATCH передаёт только изменения, благодаря чему запросы меньше и экономнее по трафику для крупных ресурсов. PUT каждый раз передаёт полное представление, независимо от того, сколько полей изменилось.

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

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

PATCH против POST

PATCH изменяет существующий ресурс по известному URI. POST создаёт новые ресурсы или инициирует обработку на стороне сервера.

PATCH использует определённую patch-семантику, например JSON Patch и JSON Merge Patch. POST полностью делегирует семантику серверу и не предписывает формат тела запроса.