Вышел RFC 10008, который определяет новый HTTP-метод — QUERY. Зачем он нужен, если у нас уже есть GET, POST и PUT?
Проблема началась со сложных запросов. GET отлично работает для простых фильтров (/api/v1/users?role=admin&status=active), но когда нужны вложенные структуры или массивы, URL раздувается, упирается в лимиты символов и начинает напоминать адскую строку. Нестандартные символы требуют кодировки, логи серверов забиваются данными, а синтаксис массивов разный у каждой реализации (?roles[0]=admin, ?roles=admin&roles=reporter, ?roles[]=admin).
Можно попробовать запихнуть тело запроса в GET. Формально RFC это не запрещают, но и не рекомендуют. На практике прокси, фаерволы и браузеры ведут себя по-разному: одни блокируют такой запрос, другие игнорируют тело, третьи интерпретируют — и пользователи за корпоративным файрволом просто не смогут открыть сайт. Менять спецификацию GET никто не будет, слишком много существующих реализаций сломается.
Остаётся POST как обходной путь. У него есть тело, но он неидемпотентен и предназначен для создания или изменения ресурсов. При автоматических повторных запросах после сбоя придётся думать о побочных эффектах. Прокси не смогут закэшировать POST — они просто не поймут, что операция read-only.
QUERY решает оба вопроса. Метод определён как безопасный и идемпотентный, как GET, но с телом запроса. Запросы можно кэшировать, но нужно аккуратно включать содержимое тела в ключ кэша.
Но есть нюансы. Поддержка QUERY пока минимальна и останется такой ещё несколько лет. Например, клиент Kreya добавил нативную поддержку только в версии 1.20, а другие клиенты, прокси и веб-серверы могут просто отклонить неизвестный метод. Старые GET-запросы с параметрами в URL никуда не делись — если они работают, менять их на QUERY не нужно. И главное: QUERY нельзя зашарить или сохранить в закладки, так как данные лежат в теле запроса. А реализовывать кэширование для QUERY сложнее — нужно анализировать тело.
Итог: QUERY заменяет POST для read-only запросов. Если обычный GET не справляется — попробуйте QUERY, но сначала проверьте поддержку инфраструктуры и не забывайте про кэширование.