Si alguna vez has intentado mandar una búsqueda compleja por GET y te has chocado con el límite de longitud de la URL, o has tirado de POST y has perdido el cacheo y la idempotencia, este método es para ti. En junio de 2026 el IETF publicó el RFC 10008, que define un método HTTP nuevo: QUERY. La idea es sencilla de resumir: una petición de solo lectura como GET, pero con la consulta viajando en el body como en POST.
En este artículo vemos qué resuelve QUERY, en qué se diferencia de GET y POST, y qué partes ya están disponibles en Laravel, porque el soporte ha empezado a aterrizar esta misma semana.
Compatibilidad y requisitos
Antes del código, deja claro qué necesitas, porque el soporte no es uniforme entre el lado que consume APIs y el lado que expone rutas.
Estándar: RFC 10008 (Proposed Standard, junio 2026). Es un método nuevo, no una modificación de GET.
Laravel — consumir APIs con QUERY: disponible en la rama 13.x. Incluye
Http::query()en el cliente HTTP y los helpers de testingquery()/queryJson().Laravel — exponer rutas QUERY:
Route::query()se ha mergeado en la rama master, es decir, llega en la próxima versión major, no en 13.x. Verifica el número de versión exacto en elcomposer.jsonde master antes de asumir nada.PHP: el servidor embebido (
php artisan serve/php -S) recibió soporte para QUERY en php-src. Si vas a probar rutas QUERY en local, comprueba tu versión de PHP.Ecosistema: Symfony ya soporta QUERY en su HTTP client. El soporte se está extendiendo por servidores, proxies y clientes de forma progresiva.
Resumen práctico: hoy puedes consumir APIs que hablen QUERY desde Laravel 13.x; para exponer tus propias rutas QUERY tendrás que esperar a la próxima major.
El problema: GET no lleva body, POST no es seguro
Cuando haces una búsqueda, lo natural es un GET con los parámetros en la query string:
GET /feed?q=foo&limit=10&sort=-published HTTP/1.1
Host: example.orgFunciona bien hasta que la consulta crece. Los problemas aparecen cuando:
La query es demasiado grande para caber en la URL. El RFC recomienda soportar al menos 8000 octetos, pero no hay garantía porque la petición pasa por sistemas intermedios que no controlas.
Metes datos sensibles en la URL, que acaban en logs, en el historial y en los marcadores.
Cada combinación de parámetros crea una URL distinta, lo que complica el cacheo.
La salida habitual es usar POST y mandar la consulta en el body:
POST /feed HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
q=foo&limit=10&sort=-publishedPero POST no es safe ni idempotente. Un intermediario que reciba ese POST no sabe que en realidad es una lectura sin efectos secundarios, así que no puede cachearlo ni reintentarlo con seguridad. Estás usando la herramienta equivocada para el trabajo.
La solución: el método QUERY
QUERY cubre exactamente ese hueco. La misma consulta anterior se expresa así:
QUERY /feed HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
q=foo&limit=10&sort=-publishedComo POST, la consulta va en el body. A diferencia de POST, QUERY es safe e idempotente por definición, lo que permite que el cacheo y los reintentos automáticos funcionen. Esta tabla, tomada del propio RFC, deja clara la posición de cada método:
Propiedad | GET | QUERY | POST |
|---|---|---|---|
Safe | Sí | Sí | Potencialmente no |
Idempotente | Sí | Sí | Potencialmente no |
Body con semántica definida | "Sin semántica definida" | Sí | Sí |
Cacheable | Sí | Sí | Solo para GET/HEAD futuros |
Un apunte importante: técnicamente GET admite un body, pero el RFC 9110 dice que ese body no tiene semántica definida, así que servidores y proxies lo ignoran o lo rechazan. GET con body nunca fue fiable. QUERY es la respuesta correcta a ese caso de uso.
Detalles del método que conviene conocer
Content-Typeobligatorio. Si falta o es inconsistente con el body, el servidor debe responder con un 4xx. No hay "content sniffing".Nuevo header
Accept-Query. Permite al servidor anunciar qué formatos de consulta acepta (por ejemploapplication/sqloapplication/jsonpath), y descubrir soporte víaOPTIONS.CORS con preflight. QUERY no está en la lista de métodos "safelisted", así que las peticiones cross-origin desde el navegador dispararán una petición preflight.
Location / Content-Location. El servidor puede devolver una URI para el resultado o para la propia consulta, de modo que peticiones posteriores puedan hacerse con un GET normal.
Cómo usarlo en Laravel
Consumir una API con QUERY (Laravel 13.x)
El cliente HTTP incorpora el método Http::query(). Manda la data en el body, igual que post(), usando el formato configurado (JSON por defecto):
<?php
use Illuminate\Support\Facades\Http;
// La consulta viaja en el body como JSON (comportamiento por defecto)
$response = Http::query('https://api.example.com/search', [
'filter' => ['status' => 'active'],
'limit' => 10,
]);Si la API espera application/x-www-form-urlencoded, encadena asForm():
<?php
use Illuminate\Support\Facades\Http;
// Cambia el formato del body a form-urlencoded
$response = Http::asForm()->query('https://api.example.com/search', [
'q' => 'laravel',
]);Ojo con un punto que confunde a mucha gente: withQueryParameters() y el argumento $query de get() no cambian y siguen controlando la query string de la URL. El método query() es el verbo QUERY, no una forma de añadir parámetros a la URL.
Testear peticiones QUERY (Laravel 13.x)
Los helpers de testing acompañan al cliente. Puedes falsear respuestas y afirmar que se envió una petición QUERY con el body correcto:
<?php
use Illuminate\Support\Facades\Http;
Http::fake([
'api.example.com/*' => Http::response(['results' => []], 200),
]);
Http::query('https://api.example.com/search', [
'filter' => 'active',
]);
// Comprueba el método y el contenido del body
Http::assertSent(function ($request) {
return $request->method() === 'QUERY'
&& $request['filter'] === 'active';
});Exponer una ruta QUERY (próxima versión mayor)
Aquí es donde tienes que esperar. Route::query() llega en la próxima major, no en 13.x:
<?php
use Illuminate\Support\Facades\Route;
// QUERY es un método safe: se trata como lectura, sin CSRF (igual que GET/HEAD/OPTIONS)
Route::query('/search', function () {
return request()->input('filter');
});Dos decisiones de diseño que conviene entender:
Sin CSRF. Al ser un método safe,
PreventRequestForgerylo trata como lectura, como hace con GET, HEAD y OPTIONS.No registra HEAD automáticamente. A diferencia de
Route::get(), que registra también HEAD,Route::query()no lo hace, porque la semántica de QUERY depende del body y un HEAD no sería equivalente.
Conclusión
QUERY llena el hueco entre GET y POST para las consultas que no caben en la URL o que no quieres exponer en la query string. Es un método safe, idempotente y cacheable con la consulta en el body, y ya tiene un RFC en Standards Track.
En Laravel el soporte ha empezado por el lado que consume: desde 13.x puedes lanzar peticiones QUERY con Http::query() y testearlas. Para exponer tus propias rutas con Route::query() tendrás que esperar a la próxima versión major. Si mantienes o consumes APIs de búsqueda, es un método que merece la pena tener en el radar.
Curso Laravel 12
Completo 2026
El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.
star Incluido en cualquier suscripción