HTTP QUERY — прикольна штука. Але давайте без революцій
Останні кілька днів вся стрічка забита новим HTTP методом QUERY (RFC 10008). Хтось вже називає це найбільшою зміною HTTP за останні 16 років, хтось прогнозує революцію в API, а хтось вже складає нові тест-кейси. Я теж почитав RFC, різні думки та обговорення. Як на мене, штука дійсно хороша. Але хайп навколо неї, як на мене, трохи завеликий.

Якщо дуже спростити, QUERY закриває стару прогалину між GET і POST. До цього у нас було два не дуже вдалі варіанти. Або пхати величезний набір фільтрів у GET-параметри, перетворюючи URL на кашу, або використовувати POST для звичайного читання даних, як це вже багато років роблять Elasticsearch, GraphQL та купа інших систем. Проблема POST у тому, що протокол не вважає його безпечним (safe). Для HTTP це потенційно операція, яка може змінювати стан системи. Через це кешування, автоматичні ретраї та інша HTTP-магія або працюють інакше, або взагалі не використовуються більшістю інфраструктури. QUERY просто каже: «ось вам body, але семантика залишається як у GET» — safe, idempotent та cacheable. Абсолютно логічне рішення.
Але є один нюанс, про який, шось мені здається, всі дружно забули. Найчастіше можна зустріти фразу «нарешті додали новий HTTP метод». Насправді HTTP-метод — це просто рядок (точніше, token у термінах HTTP). Сервер міг приймати QUERY, SEARCH чи навіть FOO ще двадцять років тому як кастомний метод. Новина не в тому, що тепер можна написати слово QUERY. Новина в тому, що тепер існує стандарт, який пояснює всій екосистемі, як поводитися з цим методом: яку семантику він має, які правила кешування застосовуються, коли його можна безпечно ретраїти. І саме це справді важливо.
Тепер давайте згадаємо, що між браузером і вашим backend дуже рідко існує пряме з’єднання. Зазвичай між ними стоїть цілий зоопарк інфраструктури: корпоративні проксі, hardware firewall, WAF, load balancer, CDN, API Gateway, IDS/IPS, SIEM та ще купа всього. І ось тут у мене виникає найбільший скепсис. Чи знає старий корпоративний файрвол десятирічної давності, шо таке QUERY? Чи знає якийсь древній F5 або проксі, який ніхто не оновлював роками? Нє, серйозно.
У кращому випадку все це скаже «ну ок» і пропустить новий метод далі. У гіршому можна отримати і 405 Method Not Allowed, і 501 Not Implemented, а іноді взагалі якийсь неочікуваний результат або блокування. І ніхто не побіжить перепрошивати тисячі старих appliance по всьому світу тільки тому, що вийшов новий RFC. Такі речі оновлюються планово — коли приходить час міняти обладнання, а не коли IETF випускає черговий документ.
Мені це дуже нагадує історію з PATCH. RFC з’явився ще у 2010 році, але на практиці купа інфраструктури його просто не підтримувала. Через це з’явилися всі ці X-HTTP-Method-Override, _method=PATCH та інші милиці. Framework-и, SDK, браузери та балансувальники поступово підтягнулися. Але лише років через десять-п’ятнадцять PATCH став настільки звичним, що ми вже навіть не замислюємося про його існування. І навіть сьогодні можна знайти enterprise-системи, які досі живуть на Method Override.
Є ще одна цікава різниця. PATCH вирішував проблему, яка була потрібна майже кожному REST API — часткове оновлення ресурсу. QUERY вирішує значно більш нішеву задачу. Тому я взагалі не здивуюся, якщо його впровадження буде ще повільнішим.
Окрема тема — AI. Вже бачив думки, що мовляв «тепер AI швидко адаптує весь світ під QUERY». Частково це правда. AI реально може допомогти оновити SDK, переписати клієнтський та серверний код, знайти місця, де POST використовується лише для читання, написати міграції чи згенерувати тести. Тут він реально проканає. Але це лише application layer.
AI не поїде по датацентрах перепрошивати hardware firewall, міняти старі F5 чи оновлювати корпоративні проксі. Такі речі живуть десятиліттями. Саме тому я майже впевнений, що перші роки ми часто будемо бачити схему «спробували QUERY — не працює — fallback на старий добрий POST», звісно, якщо API підтримує обидва варіанти. І, до речі, це теж окремий пласт тестування.
При цьому я зовсім не вважаю QUERY марною ідеєю. Навпаки, є місця, де він виглядає дуже органічно. Найбільше мені подобається потенційне використання у GraphQL. Сьогодні типовий GraphQL працює через один POST /graphql, і через нього однаково проходять і звичайні query, і mutation. Для HTTP-інфраструктури вони нічим не відрізняються, хоча по суті це абсолютно різні операції. QUERY міг би нарешті розділити їх на рівні самого протоколу: читання відправляти через QUERY, а зміни залишити на POST. Тоді кешування, ретраї, логування та rate limiting стають значно логічнішими. Не здивуюся, якщо саме в таких фреймворках QUERY почне з’являтися одним із перших.
Короче, QUERY мені подобається. RFC закриває стару прогалину між GET і POST красивим та логічним способом. Але чекати, шо завтра весь світ дружно переїде на QUERY, я б точно не став. HTTP — це взагалі не тільки про код. Це ще дофіга легасі, мережевого заліза та інфраструктури, яка живе за своїми законами. І саме вона майже завжди визначає, наскільки швидко будь-яка «революція» стане реальністю.
Тому для мене QUERY — це не революція. Це хороша еволюція HTTP. І, як показує історія PATCH, такі зміни заходять у наше життя не за місяці, а за роки.
3 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарівЧудовий розбір, дякую. Особливо сподобався акцент на тому, що «HTTP-метод — це просто рядок», а головне — стандартизація семантики safe/idempotent/cacheable. Це саме те, що відрізняє протокол від кастомного рішення.
Хочу додати важливий нюанс зі своєї практики. Навіть коли семантика методу чітко визначена в RFC, distributed middleware (проксі, кеші, балансувальники) можуть створювати temporal collisions між моментом, коли інфраструктура вирішує «це safe, можна кешувати/ретраїти», і реальним станом системи. Це та сама проблема, що з Kafka consumer: між StoreResult і CommitOffset існує crash window, і тести його не ловлять.
Ми дослідили це питання з використанням TLA+ (model checking) — виявилося, що навіть семантично «безпечні» протоколи мають несподівані колізії на рівні взаємодії middleware. Якщо цікаво, деталі в статті «Чому тести не ловлять race conditions і що з цим робити» — там якраз про те, чому формальна верифікація потрібна навіть тоді, коли RFC написаний ідеально: dou.ua/forums/topic/60608
студент, ви тільки тему про блохи вивчили?
Vitaliy, якщо маєте змістовні заперечення по суті — готовий вислухати. TLA+ і temporal collisions — це досліджена тема (Amazon, Microsoft, researchers). «Студент» і «блохи» — не аргумент.