Casi todas las APIs del mundo tienen un endpoint llamado POST /search. Funciona. Pero es una mentira pequeña: HTTP dice que POST modifica algo, y una búsqueda no modifica nada. Después de 16 años sin métodos nuevos, HTTP por fin resolvió ese hueco.
En junio de 2026 el IETF publicó el RFC 10008: The HTTP QUERY Method. Es el primer método HTTP realmente nuevo desde PATCH, en 2010.
El problema: GET no alcanza, POST miente
La consulta típica de toda la vida se ve así:
GET /feed?q=foo&limit=10&sort=-published HTTP/1.1 Host: example.org
Sencillo, hasta que la consulta crece. El RFC enumera cuatro dolores concretos:
- El límite de tamaño no se conoce. La petición pasa por proxies, CDNs y balanceadores que nadie coordinó entre sí. La recomendación mínima es soportar 8000 octetos, pero nadie te garantiza más.
- Codificar datos estructurados en una URI es ineficiente. Filtros anidados, arrays, caracteres especiales… todo termina en un string ilegible.
- Las URIs se registran en logs. Y en historiales, y en marcadores. El cuerpo de la petición, mucho menos.
- Cada combinación de filtros se vuelve un recurso distinto. Lo cual rara vez es lo que querías modelar.
La salida clásica es usar POST:
POST /feed HTTP/1.1 Host: example.org Content-Type: application/x-www-form-urlencoded q=foo&limit=10&sort=-published
Resuelve el tamaño, pero rompe el contrato. Sin conocer la API por dentro, nada en el protocolo indica que esa operación es de solo lectura. Resultado: los intermediarios no cachean, los clientes no reintentan solos, y tu búsqueda se comporta como si fuera peligrosa.
QUERY: cuerpo de POST, semántica de GET
El mismo caso, con el método nuevo:
QUERY /contacts HTTP/1.1 Host: example.org Content-Type: application/x-www-form-urlencoded Accept: application/json select=surname,givenname,email&limit=10
Igual que POST, la consulta viaja en el cuerpo. A diferencia de POST, el método es explícitamente seguro e idempotente. Eso habilita caché y reintentos automáticos sin que nadie tenga que documentarlo aparte.
Comparación rápida
| GET | QUERY | POST | |
|---|---|---|---|
| Seguro | Sí | Sí | Potencialmente no |
| Idempotente | Sí | Sí | Potencialmente no |
| Cuerpo | Sin semántica definida | Esperado | Esperado |
| Cacheable | Sí | Sí | Solo para futuros GET/HEAD |
| URI para la consulta | Sí, por definición | Opcional (Location) |
No |
Las reglas que hay que respetar
QUERY no es "POST pero bonito". El RFC es estricto en un punto: el servidor DEBE rechazar la petición si falta el Content-Type o si no coincide con el contenido. Nada de adivinar el tipo leyendo el cuerpo.
Los códigos recomendados para cuando algo sale mal:
400— falta el media type, o está declarado pero no corresponde al contenido real.415— el media type es válido pero el recurso no lo soporta.422— el formato está bien y la consulta se entiende, pero no se puede procesar. Por ejemplo, un SQL sintácticamente correcto que apunta a una tabla inexistente.406— el cliente pidió un formato de respuesta que no manejas.
Descubrimiento: ¿este endpoint soporta QUERY?
Dos caminos. El clásico, con OPTIONS:
OPTIONS /contacts HTTP/1.1 Host: example.org HTTP/1.1 200 OK Allow: GET, QUERY, OPTIONS, HEAD
Y el nuevo: el RFC también registra la cabecera de respuesta Accept-Query, que anuncia qué formatos de consulta acepta el recurso.
HEAD /contacts HTTP/1.1 Host: example.org HTTP/1.1 200 OK Accept-Query: "application/jsonpath", application/sql
Ojo con un detalle: Accept-Query es un Structured Field (RFC 9651), no una cabecera de texto libre como Accept. Se parsea distinto. Y su valor aplica a todas las URIs del servidor que compartan el mismo path: el query string se ignora.
La parte elegante: guardar la consulta como URI
Aquí es donde QUERY se pone interesante. Una respuesta exitosa puede incluir dos cabeceras:
HTTP/1.1 200 OK Content-Type: application/json Content-Location: /contacts/stored-results/17 Location: /contacts/stored-queries/42
Content-Locationapunta al resultado de esta consulta. Un GET ahí te devuelve exactamente lo mismo que acabas de recibir.Locationapunta a la consulta guardada. Un GET ahí vuelve a ejecutarla, con datos frescos, sin reenviar el cuerpo.
Eso último resuelve un problema real: una vez que el servidor te dio esa URI, tu cliente puede cambiar a GET para el polling y usar peticiones condicionales (If-None-Match, If-Modified-Since) sin volver a mandar un JSON de 40 KB cada 30 segundos.
Caché: donde está el riesgo
Las respuestas a QUERY son cacheables, pero con una condición innegociable: la clave de caché DEBE incorporar el cuerpo de la petición y sus metadatos.
Esto es más delicado que cachear un GET, porque el intermediario tiene que leer el cuerpo completo antes de poder calcular la clave. El RFC permite normalizar el contenido para mejorar la eficiencia (quitar content-encoding, normalizar JSON, etc.), pero advierte lo obvio: una normalización mal hecha produce falsos positivos, y un falso positivo es una respuesta incorrecta servida a otro usuario. Cache poisoning por la puerta de atrás.
Si tu CDN no entiende QUERY, no lo va a cachear mal: lo más probable es que lo rechace. El problema no son los que lo rechazan, son los que lo tratan como POST a medias.
Lo que todavía no puedes hacer
Seamos claros sobre el estado real, a julio de 2026:
- No hay
fetch()con QUERY. El navegador no lo manda hasta que la especificación Fetch de WHATWG lo incorpore. - Siempre habrá preflight en cross-origin. QUERY no está en la lista de métodos "CORS-safelisted", así que toda petición cross-origin arrastra un OPTIONS previo.
- Tu infraestructura puede no saber qué es. WAFs, proxies inversos, load balancers y frameworks viejos pueden rechazar el método o enrutarlo raro. Revisa changelogs antes de asumir soporte.
Traducción práctica: en 2026 QUERY es una historia de servidor a servidor y de API gateways. Y está bien, porque ahí es justamente donde vive el tráfico pesado de búsquedas, reportes y consultas internas.
¿Lo empiezo a usar?
Mi recomendación, en orden:
- No migres nada en producción todavía. Verifica primero soporte en tu framework, CDN, proxy y WAF.
- Empieza por un salto interno. Si tenés un BFF (backend-for-frontend) hablando con un servicio propio, ese hop es el laboratorio perfecto: controlás las dos puntas.
- Mantené el
POST /searchvivo. Exponé QUERY en paralelo y anunciálo conAllowyAccept-Query. Que el cliente decida. - Si cacheás, auditá la clave. Si el cuerpo no entra en la clave, apagá la caché hasta que entre.
Lo que realmente cambia
QUERY no habilita nada que no pudieras hacer antes con POST. Lo que hace es convertir una convención en un contrato. Antes, "esta búsqueda es segura, podés reintentarla" era algo que documentabas en un README y esperabas que alguien leyera. Ahora es algo que el protocolo declara y que cualquier intermediario puede entender sin conocer tu API.
Dieciséis años esperando un método nuevo, y resultó ser el que ya estábamos usando mal todos los días.
Referencia: RFC 10008 — The HTTP QUERY Method, J. Reschke, J. M. Snell, M. Bishop. IETF, junio de 2026. Standards Track (Proposed Standard). Disponible en rfc-editor.org/info/rfc10008.