Что такое идемпотентный метод в контексте API?

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

Ответ

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

Ключевая идея: Безопасность повторных операций. Если клиент не получил ответ (например, из-за таймаута сети), он может безопасно отправить запрос повторно.

Идемпотентные HTTP-методы (согласно спецификации):

  • GET — получение данных. Не изменяет состояние.
  • PUT — полное обновление ресурса. Повторный PUT с теми же данными оставит ресурс в том же состоянии.
  • DELETE — удаление ресурса. После первого успешного удаления последующие вызовы вернут тот же результат (например, 404 или 410).
  • HEAD, OPTIONS — безопасные методы.

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

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

Пример на Python:

# Идемпотентный метод: получение пользователя (GET)
def get_user(user_id: int):
    # Многократные вызовы не изменяют данные в БД
    return db.session.query(User).get(user_id)

# Идемпотентный метод: обновление пользователя (PUT)
def update_user(user_id: int, data: dict):
    # Повторный вызов с теми же `data` установит те же значения
    user = db.session.query(User).get(user_id)
    for key, value in data.items():
        setattr(user, key, value)
    db.session.commit()

# НЕ идемпотентный метод: увеличение счетчика (POST)
def increment_counter(user_id: int):
    # Каждый вызов изменяет состояние (увеличивает значение)
    db.session.execute("UPDATE counters SET value = value + 1 WHERE user_id = :uid", {'uid': user_id})
    db.session.commit()

Почему это важно для тестирования? Идемпотентность упрощает тестирование и отладку API, а также обеспечивает надежность в распределенных системах.