Чем put отличается от patch
Перейти к содержимому

Чем put отличается от patch

  • автор:

KRostyslav / PUTvsPOSTvsPATCH.md

Save KRostyslav/72712b3a9e511134ce620ae21b29af09 to your computer and use it in GitHub Desktop.

PUT or POST or PATCH?

PUT or POST or PATCH? PATCH!

TL;DR

POST для создания новых ресурсов POST для остальных кастомных глаголов PATCH для обновления ресурсов. В 99,99% на обновление уходят не все поля ('created_at' и 'updated_at' так точно) На PUT можно забить =) 

Идемпотентность

Идемпотентность это очень важный концепт в HTTP спецификации. Идемпотентный запрос — это запрос который независимо сколько раз эго отправит клиент, сервер вернет один и тот же ответ, без изменений. Другими словами, создание большого количества идентичных запросов имеет такой же эффект, как и один запрос. По HTTP спецификации GET, HEAD, PUT, и DELETE имеют этот атрибут, POST и PATCH — нет.

PUT подразумевает полное обновление независимо от того какие данные находятся по указанному URL, новыми данными. Исполюзуя PUT вы обязаны отправлять не только те поля которые вам необходимо а ВСЕ. Идемпотентность это фундаментальное свойство HTTP спецификации и должно соблюдаться для гаранрирования функциональной совместимости и масштабирования веба.

  • https://stormpath.com/blog/put-or-post
  • http://www.restapitutorial.ru/lessons/idempotency.html
  • https://habrahabr.ru/company/yandex/blog/265569/

В чем отличие метода PUT и PATCH?

Я так понимаю, что в PUT, при отсутствии записи создается новая, при ее наличии изменяются данные записи, а PATCH новую запись не создает и только изменяет ее. Верно? Тогда какие ответы и коды должны быть в PATCH, если записи нет? и в PUT какие ответы должны быть при наличии записи и при ее отсутствии?

serg002 ★★★
19.11.21 22:50:45 MSK
Последнее исправление: serg002 19.11.21 22:52:03 MSK (всего исправлений: 1)

1 2 →

Что-то вроде:
— PATCH: 404 (Not found) при отсутствии, 200 (OK) при существовании.
— PUT: 201 (Created) при отсутствии, 200 (OK) при существовании.

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

sanwashere ★★
( 19.11.21 23:11:26 MSK )
Последнее исправление: sanwashere 19.11.21 23:12:35 MSK (всего исправлений: 1)

Забей. Есть GET и POST, остальное — от лукавого.

(ну да, ну да, есть ещё OPTIONS — но это в большинстве случаев для прикладух должно быть прозрачно)

Miguel ★★★★★
( 20.11.21 01:01:00 MSK )
Ответ на: комментарий от Miguel 20.11.21 01:01:00 MSK

Есть GET и POST, остальное — от лукавого.

что б с тебя штрафы POST’ом списывались, умник

anonymous
( 20.11.21 02:38:50 MSK )

По задумке есть отличия, а по факту синоним. Не заморачивайся. Имей в виду, что от реализации к реализации разница может быть, но зачастую будет полностью отсутствовать, а сам используй PATCH, если у тебя нет прямой необходимости сделать с помощью PUT что-то сродни upsert.

WitcherGeralt ★★
( 20.11.21 07:15:44 MSK )
Последнее исправление: WitcherGeralt 20.11.21 07:25:14 MSK (всего исправлений: 2)

PUT — это замена. PATCH — это обновление. PUT’ом ты отправляешь объект полностью и заменяешь им существующий/создаёшь новый. PATCH’ем ты можешь обновлять какие-то части уже существующего объекта.

fulmar_lor ★
( 20.11.21 12:54:04 MSK )
Последнее исправление: fulmar_lor 20.11.21 12:57:37 MSK (всего исправлений: 1)

Ответ на: комментарий от fulmar_lor 20.11.21 12:54:04 MSK

+1. Если мы, к примеру, тупо транслируем REST-запрос в SQL UPDATE, то в PUT надо передавать полный список полей, в отсутствующие поля будет записан null; а PATCH не будет обновлять отсутствующие поля. (Как передавать в PATCH null, не помню.)

И да, как написал WitcherGeralt , PUT это SQL UPSERT, а PATCH – SQL UPDATE.

dimgel ★★★★★
( 20.11.21 13:13:04 MSK )
Последнее исправление: dimgel 20.11.21 13:22:08 MSK (всего исправлений: 2)

Ответ на: комментарий от anonymous 20.11.21 02:38:50 MSK

что б с тебя штрафы POST’ом списывались, умник

Два чая этому анониму, он определённо секёт фишку. =)

dimgel ★★★★★
( 20.11.21 13:20:50 MSK )
Ответ на: комментарий от dimgel 20.11.21 13:20:50 MSK

А можете разжевать фишку для несекущих? Я бы согласился с Miguel, честно говоря.

Попытка провести параллели запросов HTTP с запросами к БД — это какая-то выдуманное, искусственное упрощение. Мне кажется.

Попался тут вопрос на hh.ru что-то вроде «расскажите путь прохождения запроса в LAMP». По-моему максимально идиотский вопрос. Но подозреваю, что правильным ответом они имели ввиду что-то из этой же серии, где запрос HTTP смешан в одну кучу с запросами к БД.

Toxo2 ★★★★
( 20.11.21 13:42:08 MSK )
Ответ на: комментарий от anonymous 20.11.21 02:38:50 MSK

что б с тебя штрафы POST’ом списывались, умник

объясните, плиз, интересно, но не врубаюсь

Qwentor ★★★★★
( 20.11.21 14:03:00 MSK )
Ответ на: комментарий от Toxo2 20.11.21 13:42:08 MSK

А можете разжевать фишку для несекущих?

PUT идемпотентен, POST нет.

dimgel ★★★★★
( 20.11.21 14:16:03 MSK )
Ответ на: комментарий от dimgel 20.11.21 14:16:03 MSK

А что именно может помешать реализовать обработку POST с проверкой повтора?

Toxo2 ★★★★
( 20.11.21 14:20:34 MSK )
Ответ на: комментарий от Toxo2 20.11.21 14:20:34 MSK

PUT обязан быть идемпотентным, а POST — нет.

maxcom ★★★★★
( 20.11.21 14:22:59 MSK )
Ответ на: комментарий от Toxo2 20.11.21 14:20:34 MSK

Ничто не мешает. Каждый волен изголяться как ему заблагорассудится. В т.ч. даже нарушая стандарты (например, делая PUT неидемпотентным, потому что идемпотентность – отнюдь не очевидная задача). Однако паттерны (а REST – это паттерн) существуют в т.ч. для того чтобы облегчать понимание твоего кода другими. И чтобы не было кто в лес кто по дрова.

dimgel ★★★★★
( 20.11.21 14:25:47 MSK )
Последнее исправление: dimgel 20.11.21 14:31:29 MSK (всего исправлений: 3)

Ответ на: комментарий от dimgel 20.11.21 14:25:47 MSK

У ТС нигде не упоминается, что он говорит про REST.
Тогда понятно, спасибо.

Toxo2 ★★★★
( 20.11.21 14:32:34 MSK )
Ответ на: комментарий от Toxo2 20.11.21 14:32:34 MSK

REST – это не более чем способ использования философии и фич HTTP с максимальной эффективностью. Так что «мы говорим Ленин HTTP – подразумеваем партия REST». А кому пофиг, тем достаточно GET и POST.

dimgel ★★★★★
( 20.11.21 14:36:24 MSK )
Последнее исправление: dimgel 20.11.21 14:37:08 MSK (всего исправлений: 1)

Ответ на: комментарий от dimgel 20.11.21 14:36:24 MSK

Занятно как REST стало означать «20 минут выбираем нужный http-метод, и ещё час спорим какие http-статусы возвращать», хотя в оригинальном white paper про rest емнип вообще http не упоминался.

PolarFox ★★★★★
( 20.11.21 14:40:45 MSK )
Ответ на: комментарий от dimgel 20.11.21 14:36:24 MSK

Впрочем, про максимальную эффективность можно и поспорить. Например, GraphQL упаковывает в один HTTP-запрос несколько REST-запросов. Но исторически это уже развитие исходной идеи, по сути ей не противоречащее.

dimgel ★★★★★
( 20.11.21 14:42:28 MSK )
Последнее исправление: dimgel 20.11.21 14:49:38 MSK (всего исправлений: 1)

Ответ на: комментарий от PolarFox 20.11.21 14:40:45 MSK

Хз что там было в white paper. Вся идея – это минимум глаголов и идемпотентность. Методы выбираются тривиально из описанных выше соображений (20 минут – ну, новичку и подольше может потребоваться к этой извращенской идее привыкнуть), а статусы (как и конкретный формат сообщений) – это уже детали реализации (один хрен в статус много информации не засунешь, поэтому реальная ошибка как правило отдаётся в теле ответа).

dimgel ★★★★★
( 20.11.21 14:46:02 MSK )
Последнее исправление: dimgel 20.11.21 14:47:07 MSK (всего исправлений: 1)

Ответ на: комментарий от dimgel 20.11.21 14:36:24 MSK

Никто не знает что такое REST потому что это очень плохо определённая расплывчатая хрень, которую каждый понимает так как ему хочется.

fulmar_lor ★
( 20.11.21 15:06:43 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 15:06:43 MSK

Книжки читать не пробовали?

dimgel ★★★★★
( 20.11.21 15:12:52 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 15:06:43 MSK

Ок, ладно. 🙂 Тот твой камент выше, который я плюсанул, вполне конкретен и не расплывчат. Просто как и всякий паттерн, REST не является догмой и оставляет массу свободы и для реализации, и для люфтов/нарушений. Тем более, что паттерн не самый тривиальный. Например, уж на что простая вещь – синглтон, но и копий вокруг него сломано немеряно, и извращения встречаются типа getInstance() с параметрами.

dimgel ★★★★★
( 20.11.21 15:25:21 MSK )
Ответ на: комментарий от dimgel 20.11.21 15:25:21 MSK

Ну попробуй хотя бы вот это объяснить:

request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server.

Т.е. у меня получается не может быть базы данных, верно? Иначе же это не REST.

fulmar_lor ★
( 20.11.21 16:10:44 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 16:10:44 MSK

Ой, всё! Утомилася я.

dimgel ★★★★★
( 20.11.21 16:14:29 MSK )
Ответ на: комментарий от dimgel 20.11.21 16:14:29 MSK

Если я хочу отправить запрос на добавление книги и внутри есть поле «автор», то оно может в момент времени t1 вернуть ошибку, в момент времени t2 вернуть 201 и успешно добавить книгу. Потому что в момент времени t1 такой автор ещё не существовал в базе, а в момент t2 он уже есть. Т.е. получается запрос на добавление книги нельзя никак назвать stateless. REST это полнейший бред сивой кобылы. Есть некоторые разумные идеи в этой диссертации, но в целом это выглядит как толстый троллинг.

fulmar_lor ★
( 20.11.21 16:23:03 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 16:23:03 MSK

dimgel ★★★★★
( 20.11.21 16:28:04 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 16:23:03 MSK

Т.е. получается запрос на добавление книги нельзя никак назвать stateless.

Stateless означает, что перед отправкой запроса ты не должен устанавливать какой-то контекст, держать соединение и т. п. Вот есть stateful ftp, там надо отдельными командами устанавливать режим, менять каталог, логинится, и т.д. Получение токена доступа для rest «это другое», ты получаешь токен, который дальше нужно передавать, а в ftp ты ничего не получаешь, а факт логина записывается в этот самый state.

goingUp ★★★★★
( 20.11.21 16:36:51 MSK )
Ответ на: комментарий от dimgel 20.11.21 15:12:52 MSK

Ух, как грубо. Сразу переход на личности, класс.

Я признаю конкретные вещи, например, jsonapi — там всё понятно. А с рестом вашим идите на фиг, вы уже всех задолбали своим REST, чёртовы сектанты и фанатики. Идите в гуманитарщину и там бесконечно переливайте из путого в порожнее, не надо в айтишку с этим дерьмом лезть.

fulmar_lor ★
( 20.11.21 16:43:11 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 16:43:11 MSK

Сразу переход на личности, класс.

А то. 🙂 «Переубедить мне вас всё равно не удастся, поэтому сразу перейду к оскорблениям.» (c)

dimgel ★★★★★
( 20.11.21 16:47:18 MSK )
Ответ на: комментарий от goingUp 20.11.21 16:36:51 MSK

Stateless означает, что перед отправкой запроса ты не должен устанавливать какой-то контекст, держать соединение и т. п.

Что такое «какой-то контекст»? Если у меня есть сессия у каждого юзера на стороне сервера, и я там храню какие-то данные (возможно от предыдущих запросов), то фанатки REST говорят, что это уже не рест. Почему? А если я в базе логирую активность юзера и в зависимости от его предыдущих запросов определяю какое будет поведение у его будущих запросов?

Получение токена доступа для rest «это другое», ты получаешь токен, который дальше нужно передавать, а в ftp ты ничего не получаешь, а факт логина записывается в этот самый state.

Почему такая же логика не применятся для остальных запросов, выходящих за пределы логики логина и аутентификации? Если юзер создал сущность X, то это сохраняется на сервере и никакой токен ты не получаешь, ты просто делаешь запрос и сервер помнит, что X уже существует. Иначе ты с каждым запросом должен просто отправлять всю базу данных получается (ну или то её подмножество, которое касается твоего запроса).

fulmar_lor ★
( 20.11.21 17:14:24 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 17:14:24 MSK

stateless относится к протоколу. Не к сущностям, которыми манипулируют с помощью апи.

А если я в базе логирую активность юзера и в зависимости от его предыдущих запросов определяю какое будет поведение у его будущих запросов?

Ну смотри, допустим в апи есть функция вставки значения в БД, и два режима, просто вставляем, или вставляем и пишем в лог файл. stateful будет, если мы сначала вызываем «включить логирование», которое включает его допустим на это подключение, но не на параллельные запросы, а потом вызываем вставку. Stateless же будет вызываем вставку, передавая параметр «включить логирование». То, что запрос завершится по разному в зависимости от того, что уже есть в БД на state(full|less) не влияет, так как не относится к протоколу.

goingUp ★★★★★
( 20.11.21 17:32:24 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 17:14:24 MSK

Если не знаком с ftp, еще SQL stateful протокол. Если у тебя оборвалось соединение с БД, то ты должен опять, допустим, выставить кодировку, уровень изоляции, и т.д. Начать заново транзакцию. В HTTP оборвалось соединение — просто отправляй новый запрос в новом.

goingUp ★★★★★
( 20.11.21 17:35:10 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 16:23:03 MSK

ебанашка, тебя REST заставляет constraint на поле author добавлять?

anonymous
( 20.11.21 18:12:02 MSK )
Ответ на: комментарий от goingUp 20.11.21 17:32:24 MSK

stateless относится к протоколу.

Мы говорим про REST. REST это не протокол, поэтому к нему понятие stateless относиться не может (с чем я согласен), но тут почему-то https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm говорится, что REST должен быть stateless.

Не к сущностям, которыми манипулируют с помощью апи.

Где грань между сущностями апи и не сущностями апи? У меня есть сущность «настройки юзера», например. Если юзер меняет запросом на изменение настроек отображаемый язык в последующих запросах, то это REST или нет потому что не stateless? Настройки юзера это такая же сущность апи как и остальные. Почему нет?

Stateless же будет вызываем вставку, передавая параметр «включить логирование».

Почему настройки логирования не могут быть сущность апи?

так как не относится к протоколу.

Так в том-то и дело, что REST это не протокол и не говорит что относится к протоколу и что не относится. Это просто вообще ни о чём, получается.

fulmar_lor ★
( 20.11.21 18:13:56 MSK )
Ответ на: комментарий от anonymous 20.11.21 18:12:02 MSK

При чём тут констрейнт? Ты какой-то совсем глупенький, лучше сдрисни из треда, не мешай дядям разговаривать.

fulmar_lor ★
( 20.11.21 18:19:08 MSK )
Последнее исправление: fulmar_lor 20.11.21 18:19:50 MSK (всего исправлений: 1)

Ответ на: комментарий от fulmar_lor 20.11.21 18:19:08 MSK

при том, мамкин архитектор, что ошибку на добавление книги с еще недобавленным автором может выдать только база, в которую напрямую пишут только то, что деды разрешили в справочниках. в нормальном REST’е ты просто создаешь автора, если его еще нет в базе, но он есть в запросе, и никакой зависимости от времени и от того, что там дед создал в оракле, нет.

anonymous
( 20.11.21 18:22:44 MSK )
Ответ на: комментарий от Toxo2 20.11.21 14:32:34 MSK

С точки зрения протокола POST, PUT, PATCH не отличаются ничем. Всё остальное это только дополнительная семантика, которую, в принципе, можно и не соблюдать, всё на уровне договорённостей.

Legioner ★★★★★
( 20.11.21 18:26:21 MSK )
Ответ на: комментарий от Legioner 20.11.21 18:26:21 MSK

С точки зрения протокола POST, PUT, PATCH не отличаются ничем

какого протокола, болезный?

anonymous
( 20.11.21 18:29:36 MSK )
Ответ на: комментарий от fulmar_lor 20.11.21 18:13:56 MSK

Если юзер меняет запросом на изменение настроек отображаемый язык в последующих запросах, то это REST или нет потому что не stateless?

Это может быть stateless если мы не считаем передачу session ID состоянием, но это однозначно не REST. В HTTP и соответственно в REST язык задаётся заголовком запроса, а не меняется отдельным запросом. И это 100% stateless т.к. этот заголовок передаётся с каждым запросом.

dimgel ★★★★★
( 20.11.21 18:30:01 MSK )
Последнее исправление: dimgel 20.11.21 18:40:34 MSK (всего исправлений: 1)

Ответ на: комментарий от anonymous 20.11.21 18:29:36 MSK

HTTP. Вообще-то тут он прав. Семантические различия POST/PUT/PATCH обеспечиваются прикладным слоем, а не собственно HTTP-сервером.

Отличия POST и PUT и PATCH методов HTTP

POST метод используется для создания нового ресурса на сервере. Запрос POST содержит данные, которые будут использоваться для создания этого ресурса. Каждый раз, когда вызывается POST запрос, будет создан новый ресурс с уникальным идентификатором.

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

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

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

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

Пишу API приложение. Читаю документацию на английском, но так как с ним (английским)у меня плохо, то не совсем понятно как использовать PUT и PATCH.

PUT вроде понятно, выбирается из базы сущность и обновляются её поля, при чём все сразу.

PATCH, тоже самое, только обновляются не все поля, а выборочно.

Поправьте меня, если я не прав.
Спасибо.

  • Вопрос задан более трёх лет назад
  • 8219 просмотров

3 комментария

Оценить 3 комментария

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *