Ответ
Основное различие — в семантике обновления ресурса.
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. И не путай их, а то накосячишь так, что мало не покажется.