В чем разница между HTTP-запросами POST и PUT?

Ответ

POST и PUT — это HTTP-методы для создания или обновления ресурсов на сервере. Их основное различие заключается в идемпотентности и семантике (действии над ресурсом).

POST (Создание или выполнение действия)

  • Семантика: "Создать новый ресурс" или "Выполнить действие".
  • Идемпотентность: НЕ идемпотентен. Многократный одинаковый POST-запрос может создать несколько ресурсов.
  • URI: Обычно указывает на коллекцию ресурсов, в которую будет добавлен новый элемент.
    • Пример: POST /api/users (создать нового пользователя в коллекции users).
  • Ответ: При успешном создании обычно возвращает статус 201 Created с заголовком Location, содержащим URI нового ресурса.
POST /api/books HTTP/1.1
Content-Type: application/json

{"title": "Clean Code", "author": "Robert Martin"}

---
HTTP/1.1 201 Created
Location: /api/books/123

PUT (Полное обновление или создание)

  • Семантика: "Полностью заменить ресурс по данному URI". Если ресурс не существует, сервер может создать его.
  • Идемпотентность: Идемпотентен. Многократный одинаковый PUT-запрос даст один и тот же результат (ресурс будет создан один раз или каждый раз заменен на одно и то же состояние).
  • URI: Обычно указывает на конкретный ресурс, который будет заменен.
    • Пример: PUT /api/users/456 (полностью заменить данные пользователя с ID=456).
  • Ответ: При успешном обновлении — 200 OK или 204 No Content. При создании — 201 Created.
PUT /api/books/123 HTTP/1.1
Content-Type: application/json

{"title": "Clean Code", "author": "Uncle Bob", "year": 2008}

---
HTTP/1.1 204 No Content

Ключевые различия и практика

Аспект POST PUT
Идемпотентность Нет Да
Безопасность (не изменяет состояние сервера) Нет Нет
Типичный URI На коллекцию (/items) На конкретный ресурс (/items/{id})
Повтор запроса Может создать дубликаты Безопасен, результат будет одинаковым
Аналогия "Добавить новую запись в таблицу" "Перезаписать всю строку в таблице по ID"

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

Вывод: Используйте POST для создания, когда клиент не определяет URI нового ресурса. Используйте PUT для полного обновления существующего ресурса, когда клиент знает его точный URI. Идемпотентность PUT делает его более безопасным для автоматических повторов запросов в ненадежных сетях.

Ответ 18+ 🔞

Давай разжую про POST и PUT, чтобы ты понял наконец, в чём тут собака порылась. Это ж не просто буквы, у них характер, блядь, разный!

Представь себе бар. POST — это как ты заходишь и говоришь: «Налей мне пива, братан». Тебе наливают кружку, ставят на стол. Ты это повторишь десять раз — тебе десять кружек и нахуй сядешь. Не идемпотентно это, понимаешь? Каждый раз новый ресурс — новая кружка в жопе.

А PUT — это ты уже с кружкой подходишь к бармену и орёшь: «На, блядь, полностью обнови содержимое этой, вот этой конкретной кружки номер 123 до состояния „пиво“!» Он выливает старую хуйню, наливает пиво. Ты это повторишь хоть сто раз — в кружке 123 будет одно и то же пиво. Идемпотентно, ёпта! Результат не меняется.

Короче, на пальцах:

  • POST /api/orders — это «создай мне новый заказ, а его номер (ID) придумай сам». Отправляешь тело запроса — тебе в ответ: «Держи, мудак, заказ создан, вот его номер: 777».

    POST /api/orders HTTP/1.1
    Content-Type: application/json
    
    {"item": "Кресло", "quantity": 1}

    Сервер отвечает: «201 Created, ищи свой заказ тут: /api/orders/777».

  • PUT /api/orders/777 — это «эй, слушай сюда, я знаю про заказ 777. ВОТ ТЕБЕ ВСЁ ЕГО НОВОЕ СОСТОЯНИЕ, ПЕРЕЗАПИШИ ЕГО НАХУЙ ЦЕЛИКОМ». Если заказа 777 не было — можешь его создать. Если был — полностью перетрёшь.

    PUT /api/orders/777 HTTP/1.1
    Content-Type: application/json
    
    {"id": 777, "item": "Диван", "quantity": 1, "status": "Оплачено"} // Отправляешь ВСЕ поля!

    Сервер отвечает: «204 No Content, всё, заебись, заменил».

А PATCH — это отдельная песня. Это когда ты такой хитрожопый и говоришь: «Слушай, в заказе 777 не трогай нихуя, только поле status поменяй на „Отправлено“». Частичное обновление, ёбана.

Таблица, чтобы вообще всё встало на свои места:

Что сравниваем POST PUT
Идемпотентность (можно повторять?) Нет! Каждый раз новый ресурс. Как десять кружек пива. Да! Сколько раз ни отправляй — ресурс будет в одном состоянии. Как одна и та же кружка.
На что ссылаемся (URI) На коллекцию (/orders). «Добавь в эту папку». На конкретную хуйню (/orders/777). «Вот именно этот файл — перезапиши».
Основная задача Создать новый ресурс, ID которого неизвестен. Или выполнить какое-то действие (типа «расчитать»). Полностью заменить (или создать, если точно знаешь URI) существующий ресурс.
Аналогия из жизни «Запиши меня на приём к врачу» (тебе дадут новую запись). «Измени мою запись номер 456: поставь время на 15:00, врача на Петрова» (меняешь конкретную запись целиком).

Итог, блядь: Выбирай POST, когда создаёшь что-то новое и сервер сам решает, как это назвать (ID присвоить). Выбирай PUT, когда ты точно знаешь, как называется ресурс (его URI), и хочешь его полностью нахуй заменить. А идемпотентность PUT — это вообще магия, которая спасает от дубликатов, когда сеть глючит и запросы летят по десять раз.