← Назад к вопросам

Что такое идемпотентность HTTP метода?

2.0 Middle🔥 201 комментариев
#API и интеграции

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Определение

Идемпотентность - это свойство операции, при котором многократное выполнение с одинаковыми параметрами даёт тот же результат, что и однократное выполнение. Для HTTP методов это означает: если запрос выполнить несколько раз, состояние сервера останется неизменным (после первого выполнения).

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

GET ✓ идемпотентный

  • Не изменяет состояние сервера
  • 100 раз вызвать GET /users/123 - получишь один и тот же результат
  • Состояние на сервере: не меняется

HEAD ✓ идемпотентный

  • То же, что GET, но без body ответа

PUT ✓ идемпотентный (при правильной реализации)

  • Заменяет весь ресурс
  • PUT /users/123 с body {"name": "John"} вызванный 10 раз = 1 раз
  • После первого запроса пользователь 123 имеет name="John"
  • Повторный запрос даст тот же результат

DELETE ✓ идемпотентный (условно)

  • DELETE /users/123 вызванный 2 раза:
    • 1-й раз: удаляет ресурс, возвращает 204 No Content
    • 2-й раз: ресурс уже удалён, возвращает 404 Not Found
  • Состояние после обоих: ресурс удалён
  • Нюанс: статус-коды разные, но состояние сервера идентично

OPTIONS ✓ идемпотентный

  • Только информирует о доступных методах

НЕ идемпотентные методы

POST ✗ НЕ идемпотентный

  • Создаёт новый ресурс
  • POST /users с body {"name": "John"}:
    • 1-й раз: создан пользователь id=1
    • 2-й раз: создан пользователь id=2
    • 3-й раз: создан пользователь id=3
  • Состояние меняется! На сервере теперь 3 одинаковых пользователя вместо одного

PATCH ✗ НЕ идемпотентный (обычно)

  • Частичное обновление
  • PATCH /users/123 с {"age": "+1"} (инкремент):
    • 1-й раз: age = 31
    • 2-й раз: age = 32
    • 3-й раз: age = 33
  • Состояние меняется после каждого запроса

Практические примеры из системы PrepBro

✓ Идемпотентные операции

GET /api/v1/questions/123
→ Получаю вопрос, состояние сервера не меняется

PUT /api/v1/questions/123
Body: {"title": "Новый заголовок", "status": "published"}
→ После 1-го запроса: вопрос обновлён
→ После 2-го запроса: то же состояние

DELETE /api/v1/questions/123
→ После 1-го: удалён
→ После 2-го: уже удалён (404)
→ Результат идемпотентен

✗ НЕ идемпотентные операции

POST /api/v1/questions
Body: {"title": "Новый вопрос"}
→ После 1-го: создан вопрос id=1
→ После 2-го: создан вопрос id=2
→ РАЗНЫЕ результаты!

POST /api/v1/questions/123/answers
Body: {"text": "Мой ответ"}
→ После 1-го: создан ответ id=1
→ После 2-го: создан ответ id=2 (дубль!)
→ НЕ идемпотентно

Почему это важно?

1. Надёжность при сетевых сбоях

Если POST запрос отправился, но клиент не получил ответ:

  • Клиент может повторить: ошибка! Создастся дубль ресурса
  • Если бы это был PUT: можно безопасно повторить

2. Проектирование API

  • Используй PUT для операций замены (обновление целиком)
  • Используй POST только для создания новых ресурсов
  • Избегай в PATCH операций с инкрементами

3. Реимплементация в клиентах

  • Браузер безопасно повторит GET
  • При POST браузер спросит "Отправить данные снова?"

Решение проблемы с POST

Для безопасности повторных POST запросов используй Idempotency Key:

POST /api/v1/answers
Headers: {"Idempotency-Key": "550e8400-e29b-41d4-a716-446655440000"}
Body: {"question_id": 123, "text": "Мой ответ"}

→ 1-й запрос: создан ответ, сохранён Idempotency-Key
→ 2-й запрос с тем же key: возвращается сохранённый ответ
→ Клиент получает одно и то же - идемпотентность обеспечена!

Итого

Идемпотентные методы (GET, PUT, DELETE) безопасны повторять при сетевых проблемах. Неидемпотентные (POST) требуют специальных механизмов (Idempotency-Key) для безопасности повторов. System Analyst должен это учитывать при проектировании API.

Что такое идемпотентность HTTP метода? | PrepBro