Но что значит "обычно"? Может быть как-то иначе? Давайте разберемся!
Что такое идемпотентность в RESTful API?
Метод называют идемпотентным, если его повторный вызов с теми же параметрами не меняет состояние системы (сервера).
Простой пример с DELETE:
Отправим первый запрос:
DELETE /user/1 - удаляет пользователя с id=1
Отправим второй такой же запрос - состояние системы не меняется, пользователь был удалён при первом запросе.
Получается, результат системы один - пользователя нет!
Также рассмотрим простой пример с НЕидемпотентным методом, чтобы была понятна разница:
POST /api/users - 1-й вызов: создает юзера на ресурсе /api/users/1 (статус 201)
2-й вызов метода с теми же данными: создает нового юзера на ресурсе /api/users/2 (ещё один 201) (дубликат, но с другим id)!
Почему "обычно", а не "всегда"?
❗️Неправильная реализация бэкенда
По стандарту PUT или DELETE должны быть идемпотентны, но если разработчик сделал так, что повторный DELETE возвращает ошибку 500 или создает побочный эффект (например, меняет счётчик 💔), то метод уже не ведёт себя идемпотентно.
❗️Скрытые побочные эффекты
Пример 1:
GET /products - каждое обращение пишет в БД "пользователь смотрел каталог" и увеличивает счётчик просмотров. Получается состояние системы меняется?
GET перестал быть идемпотентным🙃🙃.
Пример 2:
GET /api/download-report?date=2025-08-10 - при каждом запросе сервер:
- генерирует новый файл отчёта,
- записывает в БД запись "Отчёт сформирован 10.08.2025 ",
- увеличивает счётчик скачиваний.
В итоге каждый вызов меняет данные в системе - значит, этот GET уже не идемпотентен 😂, хотя по стандарту должен быть.
❗️Внешние интеграции
Если у вас метод PUT или DELETE, а на стороне интеграции при каждом вызове что-то записывается/создаётся - идемпотентность нарушается.
Идемпотентность - это про договорённость в стандарте, а не автоматическую гарантию.
Даже GET можно сделать неидемпотентным, если бэкенд так запрограммирован.
#qa #api
🔚Дополнение на бусти:
Идемпотентность: Разбираем вопросы на собеседованиях. Готовые ответы + примеры