Какие HTTP-методы являются идемпотентными?

Ответ

Идемпотентный HTTP-метод — это метод, многократный вызов которого с одними и теми же данными приводит к одинаковому результату и не изменяет состояние системы после первого успешного запроса.

Идемпотентные методы:

  • GET — получение ресурса. Повторные запросы не влияют на сервер.
  • HEAD — аналогичен GET, но без тела ответа.
  • PUT — создание или полное обновление ресурса по известному URI. Повторный вызов с теми же данными оставляет ресурс в том же состоянии.
  • DELETE — удаление ресурса. После первого успешного удаления последующие запросы обычно возвращают 404 Not Found или 410 Gone, что также является идемпотентным результатом.
  • OPTIONS и TRACE — безопасные методы, не изменяющие состояние.

Неидемпотентный метод:

  • POST — создание ресурса. Каждый вызов обычно создает новый объект, изменяя состояние системы.

Пример идемпотентности PUT:

PUT /api/users/123 HTTP/1.1
Content-Type: application/json

{"name": "Alice", "role": "admin"}

Повторная отправка этого же запроса не создаст нового пользователя и не изменит результат — пользователь 123 будет иметь имя "Alice" и роль "admin".

Ответ 18+ 🔞

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

Представь, что у тебя есть кнопка. Ты её жмёшь — происходит что-то. Ты жмёшь её второй, десятый, сотый раз — и хуйня происходит одна и та же. Вот это, блядь, и есть идемпотентность. Не надо думать про «идемпотентный HTTP-метод» как про какую-то заумь, это просто про кнопку, которую можно долбить сколько влезет, и система не сломается и не наделает лишнего.

Какие методы такие крутые, что им похуй на повторения?

  • GET — это как спросить «как дела?». Спроси раз, спроси сто — ответ «нормально» не изменится, и у собеседника от твоих вопросов не прибавится ни хлеба, ни зрелищ.
  • HEAD — тот же GET, только стеснительный. Тело ответа не показывает, но суть та же.
  • PUT — вот это мощный метод, ёпта. Это команда: «Слушай сюда, по адресу /api/users/123 должен лежать юзер `{"name": "Alice", "role": "admin"}». И всё!». Отправил раз — система говорит «окей, положил». Отправил второй раз с теми же данными — система посмотрит, а там уже эта Алиса лежит, пожимает плечами и скажет «ну окей, так и есть, чё бухтеть». Нового юзера не создаст, состояние не поменяется. Идемпотентность в чистом виде, ядрёна вошь!
  • DELETE — «удали ресурс». Удалил раз — его нет. Пытаешься удалить второй раз — система тебе честно скажет: «братан, там уже пусто, хули ты доёбываешься?» (вернет 404). Результат тот же — ресурса нет. Значит, идемпотентный.
  • OPTIONS, TRACE — это вообще безобидные зверушки, они ничего не трогают.

А кто тут неидемпотентный, то есть опасный для многократного тыкания?

  • POST — вот этот, сука, подлец! Это как крикнуть «Создай что-нибудь!». Крикнешь раз — создаст один документ. Крикнешь второй — создаст второй, абсолютно такой же, и у тебя уже дубликаты. Каждый раз состояние системы меняется, плодятся сущности. Волнение ебать! Его просто так в цикл не засунешь, а то овердохуища мусора накопится.

Смотри на пример, чтобы вообще всё встало на свои места:

PUT /api/users/123 HTTP/1.1
Content-Type: application/json

{"name": "Alice", "role": "admin"}

Отправил этот запрос. Сервер взял, создал или обновил юзера с id=123, сделал его Алисой-админом. Отправил его ещё раз, с теми же данными. Сервер проверил, а такой юзер уже есть, и он уже Алиса-админ. И говорит: «Ну, ок, так и есть, чё менять-то?». Состояние системы не изменилось, результат тот же. Вот она, магия, блядь.

Короче, запомни: если метод идемпотентный — его можно слать повторно без страха всё похерить. Главный враг в этом деле — POST, с ним надо аккуратнее, а то насоздаёшь хуйни.