Нужно ли отправлять тело в GET запросах и в чем отличие PUT от PATCH?
Что проверяют
Знаете ли вы свойства методов из спецификации: безопасность, идемпотентность, кэшируемость. Вопрос отделяет тех, кто читал стандарт, от тех, кто выучил «GET читает, POST пишет», и заодно проверяет, как вы проектируете свои эндпоинты.
Как отвечать
Тело в GET отправлять не надо. Спецификация его не запрещает прямо, но и не задаёт ему смысла: сервер, прокси или кэш вправе его отбросить, а часть клиентских библиотек его просто не отправит. Параметры выборки кладут в query string; если их слишком много для адреса, делают отдельный эндпоинт поиска через POST, сознательно теряя кэширование.
PUT и PATCH:
- PUT заменяет ресурс целиком тем представлением, что пришло в теле. Поля, которых в теле нет, считаются сброшенными. PUT может и создать ресурс по указанному адресу;
- PATCH описывает изменение, а не итоговое состояние: в теле набор правок;
- PUT идемпотентен, повтор того же запроса оставляет то же состояние. PATCH идемпотентным быть не обязан: операция вида «увеличить счётчик» при повторе сработает дважды;
- коды ответа: 200 с телом, 204 без тела, 201 если PUT создал ресурс.
Где спотыкаются
Называют единственным отличием «целиком против частично» и замолкают. Спрашивают обычно ровно про идемпотентность: что произойдёт, если клиент не дождался ответа и повторил запрос.
Реализуют PUT как частичное обновление: пришло два поля, обновили два. Клиент после этого не может очистить значение, потому что null неотличим от «поле не прислали», и API перестаёт соответствовать собственной документации.
Отправляют тело в GET через клиент, который это умеет, и потом ищут, почему на проде за прокси приходит пустой фильтр. Рядом второй грех: GET с побочными эффектами. Такой адрес дёрнет за вас краулер, антивирус или предзагрузка браузера.