Чем HTTP-метод PATCH отличается от PUT в REST API?

Ответ

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

Сравнение на примере обновления пользователя с id=123:

  • PUT-запрос (полная замена): Клиент должен отправить ВСЕ поля ресурса.

    PUT /users/123 HTTP/1.1
    Content-Type: application/json
    {
        "name": "Иван",
        "email": "new@example.com", // Обновлено
        "age": 30                     // Обязательно, иначе поле будет удалено!
    }
  • PATCH-запрос (частичное обновление): Клиент отправляет только изменяемые поля.

    PATCH /users/123 HTTP/1.1
    Content-Type: application/json
    {
        "email": "new@example.com" // Только это поле будет обновлено
    }
Ключевые различия: Характеристика PUT PATCH
Семантика Полная замена Частичное обновление
Идемпотентность Да. Многократный вызов дает одинаковый результат. Не гарантируется. Зависит от формата запроса (например, операция increment неидемпотентна).
Передаваемые данные Весь ресурс Только дельта (изменения)
Форматы PATCH JSON Patch (RFC 6902), JSON Merge Patch (RFC 7396) или простой частичный JSON.

Best Practice: Используйте PATCH для оптимизации трафика и атомарного обновления отдельных полей, особенно для больших ресурсов.

Ответ 18+ 🔞

А, ну вот, опять про эту дичь с PUT и PATCH! Сидишь такой, пишешь API, и тут бац — архитектор с пеной у рта начинает орать про идемпотентность и семантику, а у тебя в голове одна мысль: «Да похуй, главное, чтоб работало». Но нет, блядь, разница-то есть, и она охуенно важная, хоть и простая, как три копейки.

Представь, у тебя есть пользователь, этакий цифровой чувак с id=123. И его надо немного подрихтовать.

Если ты берешь PUT — это как прийти к нему домой, вышвырнуть всю его старую хуйню на помойку и затащить новый, полностью укомплектованный гарнитур. Забыл про его любимый стул? Сорян, он теперь в жопе мира. PUT требует ВСЁ, до последнего поля.

PUT /users/123 HTTP/1.1
Content-Type: application/json
{
    "name": "Иван",
    "email": "new@example.com", // Меняем почту
    "age": 30                     // А это, сука, ОБЯЗАТЕЛЬНО указать, иначе поле `age` просто испарится в небытие!
}

Не отправил age? Поздравляю, ты только что сделал пользователя агентом без возраста, вечным юношей. Идемпотентно? Абсолютно. Десять раз швырнул его старые вещи и занес новые — результат один: у него только этот новый набор.

А теперь PATCH — это как хирург с ювелирной точностью, ёпта. Ты не трогаешь всю квартиру. Ты приходишь, меняешь одну кривую розетку на нормальную и сваливаешь. Всё остальное остаётся на своих местах.

PATCH /users/123 HTTP/1.1
Content-Type: application/json
{
    "email": "new@example.com" // Всё, сука. Только почту сменил. Имя и возраст остались как были.
}

Вот и вся магия. Трафика меньше, серверу проще, клиенту удобнее. Но тут, блядь, подвох: идемпотентность не гарантирована. Если твой PATCH — это «увеличить счётчик на 1», то каждый новый вызов будет давать новый результат. Это уже не чистый идемпотент, это операция с состоянием.

Короче, сводка для тех, кто в танке:

Признак PUT PATCH
Суть Полный пиздец и перезагрузка. Точечный апдейт, ювелирная работа.
Идемпотентность Да, всегда. Как молотком по яйцам — один результат. ХЗ. Зависит от того, что ты там патчишь.
Что шлёшь Весь объект, целиком. Только дельту, то, что меняется.
Форматы для PATCH Есть умные (JSON Patch), есть простые (просто JSON).

Так что best practice, блядь? Если ресурс большой и менять надо чутка — юзай PATCH. Экономия трафика — это святое. Если тебе надо гарантированно, чтоб после запроса у ресурса был ровно тот вид, который ты отправил — бери PUT и не еби мозг. Выбор за тобой, архитектор ебаный.