Идемпотентность — это свойство запроса, при котором повторное выполнение даёт тот же результат, что и первое (без побочных эффектов).
В REST API это важно, чтобы повторные запросы не приводили к изменению состояния системы (например, при сетевых сбоях или ретраях).
Пример:
PUT /users/1 с теми же данными можно вызвать 1 или 10 раз — результат один: данные пользователя обновлены, но не продублированы.
А вот POST /users — не идемпотентный, потому что каждый вызов создаёт нового пользователя.
Термин идемпотентность (idempotency) означает, что одинаковый запрос, выполненный несколько раз подряд, не изменяет результат после первого вызова.
То есть система реагирует одинаково — независимо от того, вызвали запрос 1 раз или 100 раз.
В REST API идемпотентность особенно важна для безопасных повторных вызовов — например, если клиент отправил запрос повторно из-за таймаута или сетевого сбоя.
Идемпотентные:
Не идемпотентные:
Между двух огней:
Пример идемпотентного запроса (PUT):
PUT /users/1
Content-Type: application/json{
"name": "Anna",
"age": 25
}
Повторный вызов с теми же данными ничего не изменит — пользователь останется тем же. Результат всегда одинаковый.
Пример неидемпотентного запроса (POST):
POST /users
Content-Type: application/json{
"name": "Anna",
"age": 25
}
Каждый запрос создаёт нового пользователя (id = 101, 102, 103 и т.д.). Результат меняется при каждом вызове.
Пример DELETE
DELETE /users/1
Первый вызов удаляет пользователя.
Второй — ничего не делает, потому что пользователя уже нет. Результат одинаковый — пользователь не существует.
Надёжность. Повтор запроса не должен повредить данные.
Пример: Клиент повторно отправил PUT, потому что не получил ответ.
Безопасность. API можно вызывать повторно без страха “дублирования”.
Пример: DELETE можно повторить — ресурс всё равно будет удалён.
Поддержка retry-механизмов. Удобно для интеграций и очередей.
Пример: Retry при сбое сети не создаёт дублей.
Idempotency-Key. В POST-запросах используют ключ, чтобы “зафиксировать” операцию.
Пример: POST /payments с Idempotency-Key: 123 не создаст дубль.
Когда действие по своей природе не идемпотентно (например, POST /payment),
можно сделать его идемпотентным через ключ:
POST /payments
Idempotency-Key: 123abc
Content-Type: application/json{
"amount": 1000,
"currency": "RUB"
}
Сервер сохранит результат первого вызова и при повторе с тем же ключом вернёт тот же ответ, не создавая новый платёж.
QA может проверить:
Выполнить запрос 2–3 раза подряд.
Сравнить:
статус-коды,
тело ответа,
состояние БД (не изменилось ли повторно).
Пример теста:
# первый вызов r1 = requests.put("/users/1", json={"name": "Anna"})# второй вызов r2 = requests.put("/users/1", json={"name": "Anna"}) assert r1.status_code == r2.status_code == 200 assert db.get_user(1).name == "Anna"
PUT создаёт новый ресурс вместо обновления -> неидемпотентно.
DELETE возвращает ошибку 500 при повторе -> должно быть “200 OK” или “404 Not Found”.
POST без Idempotency-Key -> возможны дубликаты при повторных запросах.
Идемпотентность — это гарантия, что повторный запрос не изменит состояние системы. Она нужна для:
надёжности при сбоях,
безопасных ретраев,
предсказуемого поведения API.
Если совсем по-простому:
PUT и DELETE можно вызвать несколько раз без последствий,
POST — нельзя (если не использовать Idempotency-Key).
Чтобы пожаловаться или сообщить об ошибке, войдите в аккаунт или зарегистрируйтесь.