Головна / Статті

Метод HTTP QUERY для команд фронтенду: безпечне читання з тілом запиту

Дізнайтеся, коли метод HTTP QUERY краще підходить за GET та POST для складних фільтрів, як використовувати його з fetch, а також яку підтримку CORS, кешування та інфраструктури потрібно.

Видавець: REACTAPP.TOP7 хв читання1546 слів

Джерела: HTTP QUERY: What Frontend Developers Should Know

Екрани пошуку та фільтрації мають постійну проблему з API. Якщо кодувати кожен фільтр у рядку запиту GET, URL стає довгим та незручним для використання; якщо надсилати фільтри у форматі JSON через POST, ви використовуєте метод, який сигналізує про зміну стану, хоча насправді йдеться про читання даних. Метод HTTP QUERY створений саме для вирішення цієї проблеми. У цій статті пояснюється, що означає QUERY, як надсилати його з додатку React за допомогою fetch, та які компоненти вашої інфраструктури, від CORS до кешу, потребують уваги перед тим, як почати від нього залежати.

Проблема, яку вирішує QUERY

Список продуктів із кількома фільтрами швидко призводить до формування запиту на кшталт цього:

/products?category=laptop&brand=Apple&minPrice=50000&maxPrice=150000&rating=4

Цей підхід працює, але кожен новий фільтр подовжує рядок, вкладені чи повторювані значення (кілька брендів, діапазон цін, порядок сортування, сторінкування) вимагають спеціальних правил кодування, а дуже довгі URL можуть досягати меж довжини на серверах, проксі та в журналах логів.

Звичайним варіантом є використання методу POST із тілом у форматі JSON. Це зручніше для реалізації на клієнтській стороні, але ускладнює формулювання контракту. Метод POST не є ні безпечним, ні ідемпотентним, тому посередники не можуть бути впевнені, що запит безшкідливий для повторного виконання, кеші за замовчуванням не будуть зберігати відповідь, а кожен, хто працює з API, мусить переглядати документацію, щоб дізнатися, що цей конкретний запит методом POST використовується лише для читання даних.

Що таке QUERY

QUERY — це метод HTTP для запиту до сервера щодо виконання запиту, описаного у вмісті запиту. Згідно з інформацією на момент написання, IETF оприлюднив його як стандарт у червні 2026 року під номером RFC 10008; перевірте його поточний статус у індексі RFC перед тим, як посилатися на нього. Замість того, щоб вкладати параметри у URL, клієнт надсилає їх у тілі запиту:

QUERY /products HTTP/1.1
Content-Type: application/json
{
  "category": "laptop",
  "brands": ["Apple", "Dell"],
  "price": {
    "min": 50000,
    "max": 150000
  }
}

Сервер обробляє запит та повертає відповідні результати. Те, що відрізняє QUERY від POST, — це його семантика: він визначається як безпечний, що означає, він не змінює цільовий ресурс, та ідемпотентний, що означає, надсилання його двічі має такий самий ефект, як і надсилання один раз. Саме ці дві властивості дозволяють клієнтам, проксі та кешам обробляти його як операцію читання. Ідемпотентність, наприклад, означає, що клієнт або проміжний елемент може автоматично спробувати знову надіслати невдалий QUERY без ризику появи дублікатів побічних ефектів, що не слід робити у випадку з POST.

Вибір між GET, POST та QUERY

QUERY не замінює інші методи. Кожен з них все ще має чітку роль:

  • GET залишається стандартним для простого отримання даних: ресурс за ID, короткий список з кількома простими параметрами.
  • POST залишається методом для операцій, які створюють або змінюють стан сервера, чи для яких небезпечно їх повторення.
  • QUERY підходить для операцій читання, де вхідні дані настільки складні, що потребують структурованого формату, такого як вкладені фільтри, масиви значень чи вирази запиту.
  • Для фронтенду перевагою є те, що складні карти стану фільтрів безпосередньо відображаються у тілі запиту, а контракт API чітко зазначає, що нічого не змінюється.

    Надсилання запиту QUERY з React

    const filters = {
      category: "laptop",
      brands: ["Apple", "Dell"],
      price: {
        min: 50000,
        max: 150000
      },
      rating: 4
    };
    

    За допомогою QUERY цей об’єкт можна серіалізувати та надіслати у такому вигляді. Наведений нижче функціонал використовує fetch із власною назвою методу та JSON-тілом:

    const searchProducts = async (filters) => {
      const response = await fetch("/api/products", {
        method: "QUERY",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify(filters)
      });
    

    Друга частина цієї ж функції перевіряє статус відповіді та аналізує результат:

      if (!response.ok) {
        throw new Error("Failed to fetch products");
      }  return response.json();
    };
    

    Окрім рядка з методом, це ідентично виклику POST. Зміна є семантичною, а не синтаксичною: запит тепер оголошує себе як запит типу QUERY. Зверніть увагу на два практичні моменти. Стандарт Fetch приводить до верхньої літери лише кілька добре відомих імен методів, тому завжди пишіть "QUERY" з великих літер. Крім того, на відміну від GET та HEAD, які функція fetch не дозволяє надсилати з тілом, для QUERY дозволено передавати тіло.

    Одна з компромісних ситуацій стосується користувацьких інтерфейсів. Фільтри, закодовані в URL, можна додати до закладок та поширювати, а також вони зберігаються після перезавантаження сторінки. Тіло запиту типу QUERY так не робить. Якщо важливі посилання, якими можна поділитися, ви все одно можете копіювати стан фільтра в URL сторінки на клієнті, одночасно надсилаючи структурований запит до API.

    Перевірте підтримку по всьому шляху запиту

    Те, що метод у процесі стандартизації, не означає, що кожен компонент, який обробляє ваш трафік, розуміє його. Запит браузера проходить крізь кілька шарів, перш ніж досягти додатку, і будь-який з них може відхилити або спотворити незнайомий метод. Перед використанням QUERY перевірте:

    • Поведінку браузера та функції fetch() у підтримуваних вами браузерах.
    • Конфігурацію CORS у API.
    • API-шлюзи та зворотні проксі.
    • CDN та кеші на периферії.
    • Проміжні сервіси для аутентифікації та авторизації.
    • Інструменти моніторингу, логування та відстеження.
    • Механізми маршрутизації та обробки тіла запиту у фреймворку бекенду.

    Деякі шари можуть дозволяти лише фіксований список методів, а інші можуть видаляти тіло запиту для невпізнаних методів. Тестуйте в режимі «кінець-кінець» у середовищі, що імітує продакшн, а не лише на локальному сервері.

    CORS завжди вимагає попереднього тестування

    QUERY не є одним із методів, дозволених для CORS (GET, HEAD та POST). Це означає, що запит QUERY з іншого джерела від браузера завжди викликає попередній запит: перед справжнім запитом браузер надсилає запит OPTIONS, щоб дізнатися, чи дозволений QUERY.

    Якщо ваша React-додаток та API знаходяться на різних доменах, сервер мусить відповісти на цей попередній запит заголовком Access-Control-Allow-Methods, який містить QUERY разом із усіма заголовками, що використовуються у вашому запиті, наприклад Content-Type. JSON-тіло також змушує виконувати попередній запит для POST, тож додаткові витрати часто не є проблемою, але метод має бути вказаний прямо.

    Це легко пропустити під час розробки. Інструменти на кшталт Postman та curl не забезпечують дотримання правил CORS, тому кінцева точка може працювати ідеально там, але зазнавати проблем у браузері.

    Кешування можливе, але є складнішим

    Відповіді на запити можна кешувати, що є однією з основних переваг цього методу порівняно з POST. Проблема полягає у тому, що відповідь залежить від тіла запиту, а не лише від URL. Розгляньмо ці два тіла запиту, надіслані до одного й того ж кінцевої точки:

    {
      "brand": "Apple"
    }
    
    {
      "brand": "Dell"
    }
    

    Вони повинні повертати різні результати. Тому кеш мусить включати зміст запиту, а також його тип медіа, у ключ кешу під час вирішення, чи можна повторно використати збережену відповідь. Кеші також можуть нормалізувати зміст (наприклад, ігнорувати незначний пробіл у JSON), щоб еквівалентні запити мали спільний запис.

    Для розробників React та Next.js урок полягає у тому, що під час кешування не слід розглядати QUERY як „GET з тілом“. Браузерні HTTP-кеші, CDN та кеші фреймворку на рівні fetch ще не можуть використовувати тіло запиту як ключ, тому потрібно перевіряти поведінку кожного рівня, а не припускати успішне знаходження у кеші.

    Як QUERY пов’язаний із GraphQL

    GraphQL часто згадується в одних і тих самих розмовах, але ці два підходи функціонують на різних рівнях. GraphQL надає мову для опису даних, які ви хочете отримати, та модель для їх обробки. QUERY — це лише дієслово на рівні передачі даних: воно визначає, як HTTP має обробляти запит із вмістом QUERY. Сьогодні клієнти GraphQL зазвичай надсилають операції за допомогою POST; теоретично сервер GraphQL може приймати операції читання через QUERY, але QUERY не замінює GraphQL, і вони можуть існувати разом залежно від дизайну API.

    Чи варто мігрувати існуючі API?

    Зазвичай ні, принаймні не лише через наявність QUERY. Якщо кінцева точка пошуку вже добре працює через GET або POST, її заміна призведе до додаткових робіт з міграцією та сумісністю за обмежену вигоду. QUERY має найбільший сенс під час проектування нової кінцевої точки, запити до якої є:

    • Тільки для читання.
  • Потенційно складно.
  • Більш природно виражається у вигляді структурованого контенту, ніж як параметри URL.
  • Ймовірно, буде корисно використовувати безпечні, ідемпотентні семантики, такі як повторні спроби та кешування.
  • Це надає командам принципову альтернативу постійному використанню методу POST, коли запит GET стає занадто складним для обробки.

    Ключові висновки

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