Можно ли считать HTTP методы синтаксическим соглашением, а не жестким набором правил
Что проверяют
Провокация. Хотят понять, повторите ли вы лозунг из туториала по REST или назовёте конкретные свойства методов, на которые опирается инфраструктура: браузер, кэш, прокси, CORS.
Как отвечать
Сервер физически не обязан ничего соблюдать: отдать список по POST ему ничто не мешает, и фреймворк не возразит. Но метод объявляет свойства, и на них рассчитывают все, кто стоит между вами и сервером:
- безопасность:
GETиHEADне должны менять состояние. Поэтому браузер, префетчер, сканер ссылок и превью в мессенджере ходят по ним без спроса; - идемпотентность:
GET,HEAD,PUT,DELETEможно повторить без нового эффекта, поэтому клиенты и балансировщики спокойно повторяют их после обрыва; - кэшируемость по умолчанию есть только у
GETиHEAD; - CORS:
GET,POSTиHEADс простыми заголовками уходят без предполётногоOPTIONS, аPUT,PATCHиDELETEвызывают его всегда.
Отсюда и формулировка ответа: соглашение, но с последствиями. Нарушив его, вы не получите ошибку компиляции, вы получите поведение, которое проявится у пользователя, а не у вас на машине.
Где спотыкаются
Прячут изменяющее действие за GET: выход из аккаунта или удаление обычной ссылкой. Такую ссылку выполняют без участия человека превью в чате, антивирусный сканер почты и префетч браузера.
Объявляют POST неправильным для обновления. Спецификация его не ограничивает, обновлять им можно, и это единственный из перечисленных методов, который не идемпотентен. Именно поэтому повтор отправки формы создаёт дубль, и лечится это ключом идемпотентности, а не заменой метода на PUT.
Путают PUT и PATCH. PUT заменяет ресурс телом запроса целиком, поэтому частичный объект затирает не переданные поля. Для точечного изменения существует PATCH, и это не стилистическая разница, а разный результат на сервере.