В чём ключевая разница между HTTP-методами PUT и PATCH?

Ответ

Основное различие — в семантике обновления ресурса.

  • PUTполная замена ресурса. Клиент должен отправить полное представление ресурса. Поля, не указанные в запросе, будут сброшены в значения по умолчанию (часто null).
  • PATCHчастичное обновление. Клиент отправляет только те поля, которые необходимо изменить. Остальные поля ресурса остаются нетронутыми.

Пример: Исходный ресурс GET /users/1{"id": 1, "name": "Alex", "age": 30, "city": "Moscow"}

  • Запрос PUT:

    PUT /users/1
    Content-Type: application/json
    
    {"name": "Alexander", "age": 31}

    Результат: {"id": 1, "name": "Alexander", "age": 31, "city": null}. Поле city было утеряно.

  • Запрос PATCH:

    PATCH /users/1
    Content-Type: application/json
    
    {"age": 31}

    Результат: {"id": 1, "name": "Alex", "age": 31, "city": "Moscow"}. Изменился только возраст.

Важное свойство: PUT является идемпотентным (многократный одинаковый вызов даёт тот же результат), а PATCH — не всегда.

Ответ 18+ 🔞

Давай разжую эту разницу, а то она у некоторых в голове как говно в проруби — вроде есть, но всё расплывается.

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

PUT — это когда ты такой: «Всё, заебался я со старым профилем, нахуй его!». И ты выгружаешь на сервер ПОЛНУЮ, сука, новую версию. Если в этой новой версии ты забыл указать, например, город — сервер тупо сбросит его в null. Идиотская операция, но такая концепция, ёпта. Повторишь её десять раз с одними данными — профиль десять раз станет одинаковым. Это и есть идемпотентность, для умников.

PATCH — это когда ты такой: «О, бля, день рождения был, возраст поправить надо». И ты шлёшь серверу только одну записочку: «Эй, дружок-пирожок, age теперь 31, остальное не трогай, я ещё не решил, куда переезжать». Сервер берёт, аккуратненько меняет только возраст, а город, имя и прочую хуйню оставляет как есть. Удобно? А то как! Но идемпотентным это говно быть не обязано — можно же десять раз слать «увеличь счётчик на 1», и он каждый раз будет меняться.

Пример, чтобы вообще пиздец всё стало ясно:

Был у нас юзер:

{"id": 1, "name": "Alex", "age": 30, "city": "Moscow"}
  • Если применить PUT с таким телом:

    PUT /users/1
    Content-Type: application/json
    
    {"name": "Alexander", "age": 31}

    То получится пиздец: {"id": 1, "name": "Alexander", "age": 31, "city": null}. Город нахуй слетел, потому что ты его в запросе не указал! PUT считает, что ты прислал полную сущность. Мудацкое поведение, но такое вот правило, блядь.

  • Если применить PATCH с таким же телом:

    PATCH /users/1
    Content-Type: application/json
    
    {"age": 31}

    То будет красота: {"id": 1, "name": "Alex", "age": 31, "city": "Moscow"}. Изменилось только то, что ты просил. Остальное — на своих местах, не тронуто, в рот меня чих-пых.

Короче, запомни: хочешь переписать весь файл с нуля — PUT. Хочешь подправить пару байт — PATCH. И не путай их, а то накосячишь так, что мало не покажется.