Какие бывают виды HTTP-запросов и их семантика
Что проверяют
Не список глаголов, а понимание свойств методов: безопасность, идемпотентность, кэшируемость и что из них следует для ретраев и прокси. Следом обычно спрашивают, почему POST не идемпотентен и как тогда безопасно повторять создание заказа.
Как отвечать
Опирайтесь на RFC 9110 и сразу связывайте с поведением:
- GET: чтение, безопасный и идемпотентный, кэшируется. Тело у GET формально не запрещено, но смысла по стандарту не имеет, и прокси вправе отклонить такой запрос;
- HEAD: как GET, но без тела ответа. Подходит, чтобы проверить существование ресурса,
Content-LengthилиETag; - POST: обработка данных ресурсом, чаще всего создание. Не идемпотентен: два одинаковых запроса могут создать два заказа. На создание принято отвечать
201 Createdс заголовкомLocation; - PUT: полная замена ресурса по известному URI или создание по нему. Идемпотентен, повтор даёт то же состояние;
- PATCH: частичное изменение. Идемпотентность не гарантирована, операция «увеличь счётчик» при повторе сработает дважды;
- DELETE: удаление, идемпотентен по состоянию, хотя второй вызов может вернуть
404; - OPTIONS: какие методы доступны, на нём же работает CORS preflight.
В Go это видно в стандартной библиотеке. С версии 1.22 http.ServeMux принимает метод в шаблоне: mux.HandleFunc("GET /users/{id}", h), параметр читается через r.PathValue("id"), а на неподходящий метод мультиплексор сам отвечает 405 с заголовком Allow. Шаблон с GET обслуживает и HEAD. А http.Transport при ошибке на переиспользованном соединении повторяет запрос сам только для идемпотентных случаев: GET, HEAD, OPTIONS, TRACE или запрос с заголовком Idempotency-Key.
Где спотыкаются
Путают безопасность с идемпотентностью. DELETE идемпотентен, но не безопасен: он меняет состояние.
Считают идемпотентность свойством, которое даёт протокол. Это обещание семантики, а выполняет его ваш обработчик: PUT, который дописывает запись в конец списка, стандарт нарушает.
Не знают, как сделать повторяемым POST. Ответ: клиент присылает ключ идемпотентности, сервер сохраняет его вместе с результатом и на повтор отдаёт тот же ответ, не создавая второй заказ.