Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Які HTTP-методи безпечні, а які ідемпотентні, і чому це важливо?

Безпечний метод не змінює стан на сервері - лише читає. Ідемпотентний метод - повторний виклик з тими самими даними дає той самий стан сервера, що й одиночний.

Метод Безпечний Ідемпотентний
GET, HEAD, OPTIONS так так
PUT ні так
DELETE ні так
POST ні ні
PATCH ні не гарантовано

Приклади:

  • PUT /users/7 {"name": "Оля"} - один раз чи п'ять, результат той самий: ім'я «Оля»;
  • DELETE /orders/42 - перший виклик видаляє, наступні нічого не змінюють (відповідь може бути 404, але стан однаковий);
  • POST /orders - кожен виклик створює нове замовлення;
  • PATCH {"balance": {"increment": 100}} - не ідемпотентний, а PATCH {"status": "paid"} - фактично ідемпотентний. Тому про PATCH кажуть «не гарантовано».

Ідемпотентність стосується стану, а не відповіді. Відповіді можуть відрізнятися (200 і потім 404 для DELETE), і updated_at може змінитися - важливо, що ефект для клієнта той самий.

Чому це важливо:

  • повтори при збоях мережі. Клієнт не отримав відповіді - він не знає, чи запит виконався. Ідемпотентний запит можна безпечно повторити. Неідемпотентний - ні: повтор POST /payments може списати гроші двічі. Для таких операцій потрібен ключ ідемпотентності;
  • проксі, браузери, бібліотеки автоматично повторюють і попередньо завантажують безпечні запити. Якщо GET /logout чи GET /orders/42/delete змінює стан, прийде «невидимий» користувач - пошуковий робот, попереднє завантаження посилань - і виконає дію;
  • кешування: відповіді на безпечні методи можна кешувати.

Типові помилки:

  • зміна стану в GET (лічильники, «відмітити прочитаним», видалення за посиланням);
  • PUT, реалізований як «додати до наявного» (тоді він не ідемпотентний);
  • POST для читання з великим тілом запиту - допустимо як виняток (складний пошук), але відповідь не кешується, і повтор не очевидно безпечний.

У Laravel CSRF-захист і так не перевіряє GET/HEAD/OPTIONS - ще одна причина не змінювати стан у них.

Докладніше в документації: Ідемпотентність

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання