В чем разница HTTP методов GET, POST, PUT, DELETE и когда их использовать
Что проверяют
Знаете ли вы свойства методов и понимаете ли, почему выбор между POST и PUT не вопрос вкуса.
Как отвечать
Разница описывается тремя свойствами: безопасность (не меняет состояние), идемпотентность (повтор не меняет результат) и наличие тела.
- GET: получение. Безопасный и идемпотентный, кэшируется, тела не имеет, параметры в адресе. Менять данные им нельзя, даже если технически получается: краулер или предзагрузка браузера выполнят его без спроса;
- POST: создание или произвольное действие. Не идемпотентен: два вызова создадут две сущности. Тело обязательно, кэшированию обычно не подлежит;
- PUT: полная замена ресурса по известному адресу. Идемпотентен: повтор с тем же телом даёт то же состояние. Может создавать ресурс, если клиент сам задаёт идентификатор;
- DELETE: удаление. Идемпотентен: после первого вызова ресурса нет, после второго тоже нет, хотя код ответа может отличаться;
- PATCH: частичное изменение. В общем случае не идемпотентен, потому что зависит от тела (замена поля идемпотентна, увеличение счётчика нет).
Как выбирать между POST и PUT при создании: если идентификатор генерирует сервер, это POST на коллекцию с ответом 201 и заголовком Location. Если идентификатор известен клиенту заранее, это PUT по адресу ресурса.
Коды ответов, которые стоит назвать: 200 с телом, 201 при создании, 204 без тела, 400 при неверных данных, 404 если ресурса нет, 409 при конфликте.
Практическая ценность идемпотентности прямая: клиент или прокси могут повторить запрос после таймаута, не зная, дошёл ли он. Идемпотентный повторять безопасно, а для POST вводят ключ идемпотентности, чтобы сервер распознал повтор и вернул сохранённый результат. Так работают платежи.
Где спотыкаются
Делают изменение данных через GET.
Считают, что PUT только обновляет и не может создавать.
Исключают DELETE из идемпотентных из-за другого кода ответа.
Не защищают создание от двойной отправки формы.