HTTP QUERY — новый способ отправлять поисковые запросы
Долгое время у разработчиков было всего два реальных способа отправить поисковый запрос на сервер: 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®ion=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
}
Сервер обрабатывает тело как критерии поиска и возвращает результат обычным ответом.
Сравнение методов
| Свойство | GET | POST | QUERY |
|---|---|---|---|
| Тело запроса | нет (по семантике) | да | да |
| Безопасный (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.
Настроить мониторинг за 30 секунд
Надежные оповещения о даунтаймах. Без ложных срабатываний