El método HTTP QUERY, definido en el RFC 10008, es un método de petición seguro y cacheable que lleva los parámetros de consulta en el cuerpo en lugar de la URL. Ofrece la expresividad de un payload POST mientras conserva la semántica de solo lectura de GET. Laravel 13.19 añadió Http::query() al cliente HTTP y el helper de prueba queryJson(); Laravel 14 incluirá un helper de primera clase Route::query(), pero hasta entonces Route::match(['QUERY'], ...) ya funciona.
El tutorial parte de una aplicación Laravel 13 nueva, instala el archivo de rutas API y Scout, y configura el driver database en .env para que Scout use consultas WHERE LIKE sobre la base de datos existente. Luego crea un modelo Article con migración y factory, añade el trait Searchable y sobrescribe toSearchableArray() para exponer solo las columnas title y body.
La ruta se registra en routes/api.php con Route::match(['QUERY'], '/articles/search', ...) y un closure que valida search como cadena obligatoria y per_page como entero opcional entre 1 y 50. Después invoca Article::search($validated['search'])->paginate($validated['per_page'] ?? 15). Como QUERY se trata como POST para la lectura de entradas, $request->input() y la validación leen el cuerpo JSON directamente. php artisan route:list muestra QUERY api/articles/search; el cliente envía un cuerpo JSON como {"search": "scout", "per_page": 10}.
Las pruebas usan el helper queryJson() introducido en Laravel 13.19; un ejemplo emplea RefreshDatabase, factories para sembrar artículos, y verifica que el endpoint devuelve el artículo correspondiente y valida el parámetro search. Desde el lado consumidor, el cliente HTTP de Laravel puede llamar al endpoint con Http::acceptJson()->query('https://example.com/api/articles/search', ['search' => 'scout']).
Un obstáculo práctico: el servidor de desarrollo integrado de PHP rechaza el método QUERY con 501 Not Implemented antes de que Laravel lo reciba, así que php artisan serve no sirve. Los entornos basados en Nginx como Laravel Herd y Valet sí pasan el verbo. Los helpers de prueba HTTP de Laravel evitan el problema porque enrutan la petición directamente dentro del framework.
Si la ruta se coloca en routes/web.php, el middleware PreventRequestForgery de Laravel 13 exigirá un token CSRF, ya que solo considera métodos de lectura a HEAD, GET y OPTIONS. Hasta que Laravel 14 excluya QUERY por defecto, el tutorial presenta dos soluciones. La primera es extender PreventRequestForgery, sobrescribir isReading() para incluir QUERY y reemplazar el middleware base en el grupo web mediante bootstrap/app.php. La segunda es aplicar withoutMiddleware(PreventRequestForgery::class) en una ruta QUERY individual. El artículo recomienda la primera porque desaparece limpiamente al actualizar. Las pruebas no dispararán el error 419 mientras el entorno sea testing, porque el middleware CSRF omite la verificación en ese entorno. De cualquier forma, los manejadores QUERY deben mantenerse de solo lectura, igual que los de GET.
Antes de llevarlo a producción, el artículo advierte que el framework es solo un eslabón de la cadena. CDN, WAF, balanceadores o proxies pueden bloquear un verbo desconocido. Los navegadores soportan fetch() con QUERY, pero los formularios HTML no; además, QUERY no es un método CORS safelisted, así que las peticiones cross-origin lanzarán un preflight. Aunque QUERY se define como cacheable, los navegadores y CDN aún no implementan ese cache. OpenAPI añadió una operación query nativa solo en la versión 3.2, publicada en septiembre de 2025, por lo que generadores y SDK antiguos pueden no describirla. Un API interno donde se controlan ambos extremos es el lugar más seguro para experimentar hoy.
Cuando se lance Laravel 14, se podrá reemplazar Route::match(['QUERY'], ...) por Route::query(...) y eliminar la sobrescritura del middleware CSRF; el resto del código no cambia.