Почему нельзя создавать объекты через DELETE и удалять через POST
Что проверяют
Знаете ли вы, что семантика HTTP-методов это контракт с инфраструктурой, а не стилевое соглашение внутри команды. Ответ уровня «так принято в REST» считается слабым, ждут последствий.
Как отвечать
У метода есть два свойства. Безопасность: запрос не меняет состояние (GET, HEAD, OPTIONS). Идемпотентность: повтор не добавляет эффекта сверх первого раза (GET, PUT, DELETE идемпотентны, POST нет).
Ключевая мысль в том, что на эти свойства опираются не люди, а машины. Браузеры и CDN кэшируют GET и не кэшируют POST. Прокси, балансировщики и HTTP-клиенты автоматически переотправляют идемпотентный запрос при обрыве соединения или таймауте. Значит создание объекта через DELETE рано или поздно приведёт к молчаливому дублю: сеть моргнула, клиент повторил, создалось два.
Дальше идут практические мелочи. Тело в DELETE спецификация не запрещает, но часть прокси, CDN и клиентских библиотек его выбрасывает, поэтому полезная нагрузка может просто не доехать. Права, аудит и правила экранирующего фильтра часто настроены по методу. Генераторы клиентов из схемы OpenAPI и роутинг фреймворков тоже строятся на методе.
Нормальная раскладка: POST на коллекцию, ответ 201 и заголовок Location, DELETE на конкретный ресурс, ответ 204, PUT для полной замены, PATCH для частичного изменения. Если операция не ложится на CRUD, это POST на отдельный ресурс-действие, а не вывернутый DELETE.
Где спотыкаются
Определяют идемпотентность как одинаковый ответ на повтор. Она про состояние сервера: после второго DELETE ресурса всё так же нет, а код при этом честно может стать 404, и это не нарушение.
Считают POST безопасным для автоматического повтора. Без ключа идемпотентности, который сервер запоминает и по которому отдаёт прежний результат, повтор создаст второй заказ или второй платёж.
Оправдывают всё тем, что HTML-формы умеют только GET и POST. Для браузерной формы это правда, для HTTP-интерфейса нет: клиент отправляет любой метод, и путать эти два случая не стоит.