HTTP QUERY — новый способ отправлять поисковые запросы

6 минут чтения
Средний рейтинг статьи — 4.8

Долгое время у разработчиков было всего два реальных способа отправить поисковый запрос на сервер: GET с параметрами в URL или POST с телом. Оба варианта имеют известные недостатки. GET упирается в ограничение длины URL и «светит» параметры в логах, а POST семантически предназначен для изменения данных, а не для чтения.

Метод QUERY призван закрыть этот пробел: это безопасный и идемпотентный способ получения данных, но с возможностью передавать критерии поиска в теле запроса.

Что такое HTTP QUERY

QUERY — новый HTTP-метод, стандартизованный IETF (RFC 10008). Проще всего думать о нём так:

QUERY — это «GET с телом запроса».

Как и GET, он:

  • безопасен (safe) — не меняет состояние сервера;
  • идемпотентен — повторный одинаковый запрос даёт тот же результат.

Но в отличие от GET, параметры поиска передаются не в строке URL, а в теле запроса — в любом удобном формате: application/x-www-form-urlencoded, JSON, а при желании и что-то более специфичное вроде выражений фильтрации.

Зачем он нужен

Разберём проблемы, которые решает QUERY.

1. Ограничение длины URL

У GET нет формального лимита в спецификации, но на практике серверы, прокси и браузеры режут URL примерно на 8 000 символов. Для сложных фильтров (много условий, длинные списки идентификаторов, вложенные структуры) этого не хватает.

GET /search?ids=1,2,3,...,5000&status=active&region=eu&... HTTP/1.1

Такой URL легко превысит лимит и вернёт 414 URI Too Long.

2. Параметры в логах и истории

Всё, что попадает в URL, оседает в логах веб-серверов, истории браузера, заголовках Referer и системах аналитики. Для чувствительных поисковых критериев это нежелательно. Тело запроса в логи по умолчанию не пишется.

3. Семантическая путаница с POST

Когда фильтр не влезает в URL, разработчики делают «поиск через POST»:

POST /search HTTP/1.1
Content-Type: application/json

{ "filter": { "status": "active" } }

Но POST не идемпотентен и не кэшируется, а промежуточные узлы имеют право считать такой запрос изменяющим состояние. Семантически это неправильно: мы всего лишь читаем данные.

QUERY устраняет компромисс — тело как у POST, но семантика чтения как у GET.

Как выглядит запрос

QUERY /search HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "filter": {
    "status": "active",
    "region": ["eu", "us"]
  },
  "sort": "created_at",
  "limit": 50
}

Сервер обрабатывает тело как критерии поиска и возвращает результат обычным ответом.

Сравнение методов

СвойствоGETPOSTQUERY
Тело запросанет (по семантике)дада
Безопасный (safe)данетда
Идемпотентныйданетда
Кэшируемостьдапрактически нетда (по замыслу)
Ограничение длины параметровда (URL)нетнет

Главный вывод из таблицы: QUERY занимает нишу, которая раньше пустовала — чтение с произвольно сложными параметрами без семантических костылей.

Кэширование

Отдельно стоит упомянуть кэширование. Поскольку QUERY безопасен и идемпотентен, ответы на него в теории можно кэшировать — в отличие от POST. Но здесь есть нюанс: ключом кэша становится не только URL, но и тело запроса. Промежуточные кэши (CDN, обратные прокси) должны уметь строить ключ с учётом body, а сейчас большинство этого не умеет. Так что кэшируемость QUERY — пока преимущество «на бумаге».

Текущая поддержка

Здесь главный сдерживающий фактор. Чтобы QUERY заработал сквозным образом, его должна понимать вся цепочка:

  • браузеры — нативная поддержка в fetch пока ограничена;
  • веб-серверы и фреймворки — многие ещё не знают метод и вернут 405 или 501;
  • прокси, балансировщики, CDN, WAF — незнакомый метод в середине цепочки может быть отброшен или заблокирован.

Отсюда практический вывод: в publicly-facing API QUERY сегодня применять рискованно. А вот во внутренних сервисах, где вы контролируете обе стороны и всё, что между ними, — уже вполне можно экспериментировать.

Стоит ли переходить прямо сейчас

Короткий ответ — зависит от того, где именно.

  • Внутренние сервисы под вашим контролем — можно пробовать: сложные фильтры станут чище, а инфраструктуру вы знаете.
  • Публичный API и браузерные клиенты — рано. Слишком много промежуточных узлов, которые метод пока не поддерживают. Разумнее подождать, пока подтянутся браузеры, прокси и CDN.

Хорошая новость в том, что переход не обязан быть резким: сервер может одновременно принимать и POST /search, и QUERY /search, постепенно переводя клиентов на новый метод по мере роста поддержки.

Итоги

QUERY — логичное дополнение к набору HTTP-методов, закрывающее давнюю проблему «сложного чтения».

Кратко:

  • QUERY — это безопасный и идемпотентный запрос с телом, «GET с body»;
  • решает ограничение длины URL, утечку параметров в логи и семантическую путаницу с POST;
  • в теории кэшируется, но реальные кэши пока не готовы;
  • сквозная поддержка (браузеры, прокси, CDN) ещё догоняет стандарт.

Если вы отвечаете за доступность API, помните: новые методы — это и новые точки отказа. Прежде чем катить QUERY в прод, стоит убедиться, что каждый узел на пути запроса действительно его понимает — и держать проверку доступности эндпоинта под мониторингом, чтобы вовремя заметить, если где-то в цепочке метод начнёт отдавать 405.

6 минут чтения
Средний рейтинг статьи — 4.8

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний