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

«Какие HTTP-методы являются идемпотентными и почему?» — вопрос из категории HTTP и веб-протоколы, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Список идемпотентных методов:

Метод Объяснение идемпотентности
GET Только получает данные. Не изменяет состояние ресурса. Повторные вызовы возвращают один и тот же ответ (если данные не изменились другим способом).
HEAD Аналогичен GET, но возвращает только заголовки ответа без тела.
PUT Используется для полного обновления ресурса по известному URI. Повторная отправка одного и того же запроса PUT завершится с тем же результатом: ресурс будет иметь состояние, описанное в первом запросе.
DELETE Удаляет ресурс. После первого успешного вызова ресурс удален. Последующие вызовы вернут тот же результат (например, 404 Not Found или 410 Gone), не изменяя состояние системы дальше.
OPTIONS Возвращает поддерживаемые методы для ресурса. Не изменяет состояние.

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

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

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

Сколько бы раз ни был отправлен этот запрос, пользователь с id=123 в итоге будет иметь имя "Alice" и роль "admin". Не создастся новых пользователей.

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

  • POST: Используется для создания ресурса. Каждый вызов POST создает новый ресурс, что приводит к разному состоянию сервера.

    POST /api/users HTTP/1.1
    Content-Type: application/json
    
    {"name": "Bob"}

    Повторные вызовы создадут несколько пользователей с именем "Bob".

  • PATCH: Часто неидемпотентен, так как используется для частичного обновления. Результат может зависеть от текущего состояния ресурса. Например, инкремент счетчика ({"op": "increment", "path": "/counter"}) при каждом вызове даст разный результат.

Важность для тестирования: Понимание идемпотентности критично для:

  • Тестирования надежности: Проверка, что повторная отправка запроса (например, из-за таймаута сети) не приводит к некорректному состоянию (двойное списание, создание дублей).
  • Проектирования API: GET, PUT, DELETE должны быть идемпотентными для предсказуемости работы API.