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

Ответ

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

Основным неидемпотентным HTTP-методом является POST.

POST

  • Назначение: Чаще всего используется для создания нового ресурса.
  • Почему неидемпотентен: Каждый успешный POST запрос создает новую сущность. Отправка двух одинаковых POST запросов приведет к созданию двух идентичных ресурсов с разными идентификаторами.

Пример:

import requests

# Первый запрос создает пользователя с id=1
response1 = requests.post('https://api.example.com/users', json={'name': 'Alice'})

# Второй идентичный запрос создает пользователя с id=2
response2 = requests.post('https://api.example.com/users', json={'name': 'Alice'})

# Результат: в системе два пользователя с именем 'Alice'

Спорный случай: PATCH

Метод PATCH может быть как идемпотентным, так и неидемпотентным, в зависимости от операции.

  • Идемпотентный PATCH: PATCH /users/123 {'email': 'new@example.com'}. Повторные вызовы не изменят email после первого.
  • Неидемпотентный PATCH: PATCH /posts/1 {'action': 'increment_likes'}. Каждый вызов будет увеличивать счетчик лайков.

Почему PUT и DELETE считаются идемпотентными?

  • PUT: Этот метод предназначен для полного обновления или создания ресурса по известному URI. Запрос PUT /users/123 {'name': 'Bob'} при первом вызове изменит имя на "Bob". Все последующие вызовы с теми же данными не изменят состояние ресурса — имя так и останется "Bob".
  • DELETE: Первый запрос DELETE /users/123 удалит ресурс. Все последующие запросы на тот же URI вернут ошибку (например, 404 Not Found), но состояние системы (отсутствие ресурса) меняться уже не будет.

Ответ 18+ 🔞

Давай разберем эту дичь, чтобы не быть, как тот Герасим, который нихуя не понимал, а только "Му-му" мычал.

Вот представь, ты в баре заказываешь пиво. Говоришь бармену: "Давай одно пиво". Это как GET — ты просто запрашиваешь, хуйня случается. Он тебе приносит — всё, конец истории. Сколько раз ни проси — он будет приносить одно и то же пиво, пока оно в холодильнике есть. Идемпотентно, блядь.

А теперь неидемпотентная операция, пиздец какой. Это когда ты говоришь: "Запиши мне в долг одну кружку пива". Это — POST. Бармен берёт свою грязную тетрадку и пишет: "Васян — 1 пиво". Ты говоришь: "А ну-ка, повтори, я не расслышал". Он, тупой, опять берёт и пишет: "Васян — ещё 1 пиво". И вот ты уже должен не одну, а две кружки, сука! Каждый раз, когда ты повторяешь эту команду, состояние мира (а именно — твой долг в этой поганой тетрадке) меняется. Это и есть неидемпотентность, ёпта. Один и тот же запрос — разный итог.

Главный по неидемпотентности — POST. Он как раз для такого: "создай что-то новое, блядь".

import requests

# Первый раз: создал Алису №1
response1 = requests.post('https://api.example.com/users', json={'name': 'Alice'})
# Второй раз, на тебе, создал Алису №2, её клон-близнец!
response2 = requests.post('https://api.example.com/users', json={'name': 'Alice'})
# Итог: две Алисы, нихуя себе клонирование. Серверу похуй, он просто плодит сущности.

А вот с PATCH — история интересная, как с хитрой жопой. Он может быть и так, и сяк.

  • Если ты патчишь почту — PATCH /users/123 {'email': 'new@mail.ru'} — то после первого раза почта поменялась. Тыкай в неё сто раз — она уже новая, больше не изменится. Идемпотентно.
  • А если ты патчишь счётчик лайков — PATCH /posts/1 {'action': 'increment_likes'} — то это пиздец. Каждый твой клик будет прибавлять +1. Тыкай сто раз — получишь сто лайков. Это уже чистый, блядь, неидемпотентный пиздец.

А PUT и DELETE — они вроде как правильные пацаны, идемпотентные.

  • PUT — это как сказать: "Поставь на полку именно эту бутылку водки". Поставил — и всё. Повторяй хоть двадцать раз — на полке будет одна и та же бутылка. Состояние мира не меняется.
  • DELETE — это "выбрось эту бутылку в окно". Первый раз — бух, бутылки нет. Второй раз командуешь — а её уже нет, выброшена! Ошибку, может, получишь, но новую бутылку из ниоткуда не создашь и ту же самую дважды не выбросишь. Состояние (отсутствие бутылки) — стабильное.

Вот и вся философия, блядь. Главное — запомни: POST — это как заказ в баре, который можно случайно продублировать и влететь на овердохуища денег. Будь осторожен с ним, чувак.