Статьи

Методы REST / HTTP: POST против PUT против PATCH

Каждый HTTP-запрос состоит из метода (иногда называемого глаголом ), который указывает действие, которое должно быть выполнено на идентифицированном ресурсе.

При создании веб-сервисов RESTful HTTP-метод POST обычно используется для создания ресурса, а PUT – для обновления ресурса. Хотя это нормально в большинстве случаев, также может быть целесообразно использовать PUT для создания ресурса. PATCH является альтернативой для обновлений ресурсов, поскольку позволяет частичные обновления.

В целом мы можем сказать:

  • POST-запросы создают дочерние ресурсы на сервере, определяемом URI. POST также используется как общая операция обработки
  • PUT-запросы создают или заменяют ресурс на клиентском URI
  • PATCH запрашивает обновление частей ресурса на определенном клиентом URI

Но давайте посмотрим немного подробнее и посмотрим, как эти глаголы определены в спецификации HTTP. Соответствующей частью здесь является раздел 9 HTTP RFC (2616) .

ПОЧТА

RFC описывает функцию POST как:

Метод POST используется для запроса, чтобы исходный сервер принял объект, включенный в запрос, в качестве нового подчиненного ресурса, идентифицируемого Request-URI в строке запроса.

Это позволяет клиенту создавать ресурсы, не зная URI для нового ресурса. Например, мы можем отправить запрос POST в / projects, чтобы создать новый проект. Теперь сервер может создать проект в качестве нового подчиненного объекта / project , например: / projects / 123 . Таким образом, при использовании POST для создания ресурса сервер может определить URI (и, как правило, ID) вновь создаваемых ресурсов.

Когда сервер создал ресурс, он должен ответить кодом состояния 201 (Создано) и заголовком Location, который указывает на вновь созданный ресурс.

Например:

Запрос:

1
2
3
4
5
6
7
POST /projects HTTP/1.1
Content-Type: application/json
 
{
    "name": "my cool project",
    ...
}

Отклик:

1
2
HTTP/1.1 201 Created
Location: https://cool.api.com/projects/123

ПОСТ не идемпотент . Поэтому отправка одних и тех же запросов POST несколько раз может привести к созданию нескольких ресурсов. В зависимости от ваших потребностей это может быть полезной функцией. Если нет, вы должны провести некоторую проверку и убедиться, что ресурс создается только один раз на основе некоторых пользовательских критериев (например, имя проекта должно быть уникальным ).

RFC также сообщает нам:

Действие, выполняемое методом POST, может не привести к ресурсу, который может быть идентифицирован с помощью URI. В этом случае либо 200 (ОК), либо 204 (Нет содержимого) – это соответствующий статус ответа, в зависимости от того, включает ли ответ объект, который описывает результат.

Это означает, что POST не обязательно должен создавать ресурсы. Его также можно использовать для выполнения общего действия (например, запуска пакетного задания, импорта данных или обработки чего-либо).

ПОЛОЖИТЬ

Основное различие между POST и PUT заключается в различном значении URI запроса. HTTP RFC говорит:

URI в запросе POST идентифицирует ресурс, который будет обрабатывать вложенную сущность. [..] Напротив, URI в запросе PUT идентифицирует объект, заключенный в запросе [..], и сервер НЕ ДОЛЖЕН пытаться применить запрос к какому-либо другому ресурсу.

Для запросов PUT клиент должен знать точный URI ресурса. Мы не можем отправить запрос PUT в / projects и ожидать, что новый ресурс будет создан в / projects / 123 . Вместо этого мы должны отправить запрос PUT непосредственно в / projects / 123 . Поэтому, если мы хотим создать ресурсы с PUT, клиент должен знать (как генерировать) URI / ID нового ресурса.

В ситуациях, когда клиент может сгенерировать URI / ID ресурса для новых ресурсов, фактически PUT должен быть предпочтительнее POST. В этих случаях создание ресурса обычно идемпотентно , что является явным намеком на PUT.

Хорошо использовать PUT для создания и обновления ресурсов. Таким образом, отправка запроса PUT в / projects / 123 может создать проект, если он не существует, или заменить существующий проект. Коды состояния HTTP должны использоваться для информирования клиента, если ресурс был создан или обновлен.

HTTP RFC сообщает нам:

Если новый ресурс создан, сервер происхождения ДОЛЖЕН проинформировать пользовательский агент через ответ 201 (Создано). Если существующий ресурс модифицируется, то должны быть отправлены коды ответа 200 (ОК) или 204 (Нет содержимого), чтобы указать успешное завершение запроса.

Вообще говоря, если точный URI ресурса известен и операция идемпонентна , PUT обычно является лучшим выбором, чем POST. В большинстве случаев это делает PUT хорошим выбором для запросов на обновление.

Однако есть одна особенность, которую следует помнить при обновлении ресурсов. Согласно RFC, PUT должен заменить существующий ресурс новым. Это означает, что мы не можем делать частичные обновления. Итак, если мы хотим обновить одно поле ресурса, мы должны отправить запрос PUT, содержащий полный ресурс.

PATCH

Метод HTTP PATCH определен в RFC 5789 как расширение ранее упомянутого HTTP RFC. В то время как PUT используется для замены существующего ресурса, PATCH используется для частичного изменения ресурса.

Цитируя RFC:

В PATCH, [..], вложенный объект содержит набор инструкций, описывающих, как ресурс, находящийся в данный момент на исходном сервере, должен быть модифицирован для создания новой версии. Метод PATCH влияет на ресурс, идентифицируемый Request-URI, и он также МОЖЕТ иметь побочные эффекты на других ресурсах;

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

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

PATCH не является ни безопасным, ни идемпотентным .

Возможно, вам интересно, в каких ситуациях частичное обновление ресурса не идемпотентно. Простым примером здесь является добавление элемента в существующий список ресурсов, например, добавление товара в корзину. Многократные (частичные) запросы на обновление могут добавлять товар несколько раз в корзину.

Опубликовано на Java Code Geeks с разрешения Михаэля Шаргага, партнера нашей программы JCG. Посмотрите оригинальную статью здесь: REST / HTTP методы: POST vs. PUT vs. PATCH

Мнения, высказанные участниками Java Code Geeks, являются их собственными.