Какие базовые HTTP методы существуют и их альтернативы
Что проверяют
Знаете ли вы семантику методов, а не только соответствие CRUD. Главное здесь безопасность и идемпотентность, и следом почти наверняка спросят, почему нельзя просто повторить упавший POST.
Как отвечать
Семантику методов сейчас задаёт RFC 9110. Пройдитесь по ним с двумя свойствами: безопасный (не меняет состояние) и идемпотентный (повтор даёт тот же результат на сервере):
- GET: чтение, безопасный и идемпотентный, кэшируется. Тело у GET не имеет определённой семантики, фильтры идут в query-параметры;
- HEAD: как GET, но без тела ответа. Альтернатива GET, когда нужны только заголовки: размер,
ETag, существование ресурса; - POST: создание или действие, не идемпотентный. Для платежей повтор делают безопасным через заголовок
Idempotency-Key; - PUT: полная замена ресурса по известному URI, идемпотентный;
- PATCH: частичное изменение, альтернатива PUT. По стандарту идемпотентным не считается;
- DELETE: удаление, идемпотентный: повторный вызов может вернуть 404, но состояние уже не изменится;
- OPTIONS: какие методы поддерживает ресурс, на нём держится preflight в CORS.
В Python это видно по фреймворкам. В FastAPI это декораторы @app.get, @app.put, @app.patch, в DRF у ModelViewSet действия list и retrieve висят на GET, create на POST, update на PUT, partial_update на PATCH, destroy на DELETE.
Про альтернативы стоит сказать шире. HTML-формы умеют только GET и POST, поэтому остальные методы иногда туннелируют через POST с заголовком X-HTTP-Method-Override. RPC-подходы (JSON-RPC, GraphQL) почти всё делают через POST. Для сложного поиска с телом в IETF обсуждают новый безопасный метод QUERY.
Где спотыкаются
Считают PUT и PATCH синонимами. PUT заменяет ресурс целиком, и поля, которых нет в запросе, по смыслу должны исчезнуть или сброситься.
Делают изменяющие действия через GET, например GET /users/5/delete. Такой адрес дёрнет краулер, сканер ссылок в почте или предзагрузка браузера.
Путают идемпотентность с одинаковым ответом. Второй DELETE вернёт 404, и это нормально, важно состояние сервера.