La méthode HTTP QUERY est une nouvelle méthode de requête, définie dans la RFC 10008 (juin 2026), qui envoie une requête dans le corps de la requête et est à la fois sûre et idempotente. Considérez-la comme GET avec un corps : vous obtenez l’espace de POST pour les filtres complexes et les garanties de GET pour la mise en cache et les nouvelles tentatives automatiques.
Si vous avez fourré un filtre de 3 Ko dans une URL, ou envoyé une recherche en lecture seule en POST et vu votre cache et votre logique de nouvelle tentative l’ignorer, QUERY est la solution. Ce guide couvre ce que dit la spécification, comment QUERY se compare à GET et POST, ce qui la prend en charge aujourd’hui, et comment tester un point de terminaison QUERY avec votre agent de codage.
Qu’est-ce que la méthode HTTP QUERY ?
QUERY est une méthode HTTP qui demande à la ressource cible d’exécuter la requête décrite dans le contenu de la requête et de renvoyer le résultat. Le corps de la requête et son Content-Type définissent la requête. La méthode est sûre (le client n’attend aucun changement d’état) et idempotente (la répéter a le même effet), de sorte que les clients, les proxys et les caches peuvent la réessayer et la mettre en cache comme GET.
La spécification est RFC 10008, « The HTTP QUERY Method », une norme proposée publiée en juin 2026 par Julian Reschke (greenbytes), James M. Snell (Cloudflare) et Mike Bishop (Akamai). L’IANA l’a ajoutée au Registre des méthodes HTTP avec « sûre : oui, idempotente : oui », juste à côté de la méthode SEARCH de l’ère WebDAV qu’elle a failli devenir.
Une requête QUERY ressemble à ceci :
QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json
select=surname,givenname,email&limit=10&match=%22email=*@example.*%22
Le serveur répond avec 200 OK et le résultat dans le corps.
Pourquoi GET et POST ne suffisaient pas
Vous aviez deux options pour une lecture complexe avant QUERY, et les deux fuient.
GET met tout dans l’URL. La RFC 10008 énumère quatre problèmes à ce sujet :
- Les limites de taille sont inconnues à l’avance, car une requête traverse de nombreux systèmes. RFC 9110 recommande seulement que les émetteurs et les destinataires prennent en charge au moins 8 000 octets.
- Encoder des données structurées dans un URI valide est un gaspillage.
- Les URI sont journalisés et mis en favori bien plus souvent que les corps de requête, ce qui pose un problème de confidentialité pour les filtres sensibles.
- Chaque combinaison d’entrées de requête devient sa propre ressource.
GET avec un corps n’est pas non plus la réponse. La RFC 9110 indique que le contenu d’une requête GET n’a pas de sémantique définie. Certains serveurs le lisent, d’autres l’ignorent, et certains proxys rejettent la requête. Vous ne pouvez pas compter dessus sur l’ensemble du trajet.
POST fonctionne, mais il ment sur l’intention. Une recherche en POST fonctionne très bien, mais rien n’indique à un client, un cache, un proxy ou une bibliothèque de nouvelles tentatives que l’opération est en lecture seule. Les caches l’ignorent donc et les clients ne la réessaient pas après une connexion interrompue. Si vous avez dû ajouter de force une clé d’idempotence à une simple lecture juste pour que les nouvelles tentatives soient sûres, vous l’avez ressenti.
QUERY conserve le corps de POST et ajoute les garanties de GET.
QUERY vs GET vs POST
Voici la comparaison, basée sur le tableau 1 de la RFC 10008 :
| Propriété | GET | QUERY | POST |
|---|---|---|---|
| Sûre | Oui | Oui | Potentiellement non |
| Idempotente | Oui | Oui | Potentiellement non |
| Corps de la requête | Aucune sémantique définie | Attendu, définit la requête | Attendu |
| URI de la requête elle-même | Oui, par définition | Facultatif, via Location |
Non |
| URI du résultat | Facultatif, via Content-Location |
Facultatif, via Content-Location |
Facultatif, via Content-Location |
| Cachable | Oui | Oui, le corps fait partie de la clé de cache | Uniquement pour un GET ou HEAD ultérieur |
| Preflight CORS depuis les navigateurs | Pas pour les requêtes simples | Toujours | Pas pour les requêtes simples |
En bref : utilisez GET lorsque la requête tient confortablement dans l’URL, QUERY lorsqu’elle ne le fait pas, et POST uniquement lorsque la requête change l’état. Pour un rappel sur les méthodes classiques, consultez nos guides sur les méthodes HTTP et GET vs POST.
Ce que définit la RFC 10008
Le Content-Type est obligatoire
Les serveurs DOIVENT faire échouer une QUERY dont le Content-Type est manquant ou incohérent avec le corps. La RFC recommande ces codes d’état :
- 400 Bad Request : aucun type de média, ou un type qui ne correspond pas au contenu. Les serveurs ne peuvent pas deviner le type à partir du corps et passer outre.
- 415 Unsupported Media Type : la ressource ne prend pas en charge ce format de requête.
- 422 Unprocessable Content : le format est correct mais la requête ne peut pas s’exécuter, par exemple du SQL qui nomme une table inexistante.
- 406 Not Acceptable : le client a demandé un type de réponse que la ressource ne peut pas produire.
Location et Content-Location
Un serveur peut renvoyer deux en-têtes facultatifs qui transforment une QUERY en quelque chose que vous pouvez GET plus tard :
Content-Locationpointe vers le résultat stocké de cette exécution spécifique. Il peut être temporaire.Locationpointe vers la requête stockée elle-même. Un GET dessus réexécute la requête avec des données fraîches, sans renvoyer le corps.
La RFC suggère que les clients passent à GET sur l’URI Location pour les requêtes répétées, car la mise en cache de GET est plus simple. Si vous renvoyez l’un ou l’autre de ces en-têtes pour une requête contenant des données sensibles, l’URI NE DOIT PAS contenir de parties sensibles du corps d’origine.
Mise en cache
Les réponses QUERY sont cachables. La clé de cache DOIT inclure le contenu de la requête et les métadonnées associées, comme le type de média. Les caches PEUVENT d’abord normaliser le corps, par exemple en supprimant l’encodage de contenu ou en normalisant le JSON pour un type +json, afin d’obtenir plus de correspondances. La spécification avertit qu’une mauvaise normalisation peut renvoyer la mauvaise réponse, donc attendez-vous à ce que les CDN soient prudents ici.
Redirections
Un 301, 302, 307 ou 308 signifie « envoyer la même QUERY vers le nouvel URI ». Contrairement à POST, une QUERY ne doit pas être réécrite en GET sur un 301 ou un 302. Un 303 See Other signifie « récupérer le résultat avec un GET sur cet URI ».
L’en-tête Accept-Query
Accept-Query est un nouvel en-tête de réponse qui annonce la prise en charge de QUERY et les formats de requête qu’une ressource accepte. C’est une liste de champs structurés, alors analysez-la comme telle :
Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"
Les clients peuvent aussi découvrir la prise en charge avec OPTIONS et lire l’en-tête Allow, ou simplement envoyer la QUERY et gérer un 405 Method Not Allowed.
Quels outils prennent en charge QUERY aujourd’hui ?
La prise en charge est inégale, alors testez votre propre pile. Voici ce que nous avons confirmé le 28 octobre 2026 :
| Outil | Résultat |
|---|---|
Serveur http de Node.js 24 |
http.METHODS inclut QUERY ; un serveur simple a reçu la méthode et le corps |
fetch de Node.js 24 |
A envoyé une QUERY avec un corps JSON |
| curl 8.7 | curl -X QUERY avec -d a envoyé la méthode et le corps |
http.client de Python 3.14 |
A envoyé une QUERY avec un corps |
| OpenAPI 3.2 | L’objet Path Item possède un champ query pour les opérations QUERY |
| Apidog CLI 2.2.12 | Le schéma endpoint-create accepte "method": "query" |
Voici l’appel curl que nous avons utilisé contre un serveur Node local :
curl -i -X QUERY http://localhost:3000/products \
-H "Content-Type: application/json" \
-d '{"q":"running shoe","limit":2}'
La norme Fetch interdit un corps uniquement sur GET et HEAD, donc les navigateurs peuvent envoyer une QUERY avec un corps. Cependant, QUERY ne fait pas partie des méthodes CORS dispensées de preflight, donc chaque QUERY inter-origine déclenche un preflight. Votre serveur doit lister QUERY dans Access-Control-Allow-Methods.
Les lacunes se situent au milieu du réseau : les proxys inverses, les passerelles API, les WAF et les CDN qui mettent les méthodes sur liste d’autorisation ou ne font pas du corps la clé de leur cache. Vérifiez chaque saut avant de déployer. La newsletter APIs You Won’t Hate note que de nombreux frameworks web gèrent déjà QUERY directement ou via un routage de méthodes personnalisées.
Comment adopter QUERY sans casser les clients
Vous n’êtes pas obligé de supprimer vos points de terminaison de recherche POST.
- Ajoutez QUERY à côté de la route POST. Pointez les deux vers le même gestionnaire. Les nouveaux clients utilisent QUERY ; les anciens continuent de fonctionner.
- Faites-en la promotion. Renvoyez
Accept-Querysur la ressource et incluezQUERYdansAllowsur les réponsesOPTIONSet405. - Imposez le Content-Type. Renvoyez 400 ou 415 comme le recommande la RFC, et 422 pour les requêtes qui s’analysent mais ne peuvent pas s’exécuter.
- Prévoyez un repli sur 405 ou 501. Les clients doivent réessayer le même corps en POST lorsqu’un saut rejette QUERY.
- Corrigez CORS. Ajoutez
QUERYàAccess-Control-Allow-Methodspour les clients navigateur. - Décidez de la mise en cache. N’activez la mise en cache partagée que là où votre cache utilise le corps comme clé. Sinon, renvoyez un URI
Locationet laissez les clients le GET. - Documentez-la. Dans OpenAPI 3.2, définissez l’opération sous
query:sur l’élément de chemin :
openapi: 3.2.0
paths:
/products:
query:
summary: Search products
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductQuery'
responses:
'200':
description: Matching products
Les filtres courts et simples peuvent rester sous forme de chaînes de requête sur GET. La RFC 10008 elle-même indique que si votre requête est aussi courte, GET est probablement le meilleur choix.
Laissez votre agent de codage tester un point de terminaison QUERY avec Apidog CLI
Une nouvelle méthode signifie vérifier le cas nominal, chaque code d’erreur et la route de repli. Confiez cela à Claude Code, Codex ou Cursor et laissez-le piloter l’Apidog CLI.
Installez la CLI, connectez-vous et ajoutez la compétence Apidog à votre agent :
npm install -g apidog-cli@latest
apidog login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
Ensuite, donnez à votre agent une invite :
In Apidog project <projectId>, add a QUERY /products endpoint that takes a
JSON body {q, limit}. Create test cases that assert 200 with an array for a
valid body, 415 for Content-Type text/plain, and 400 with no Content-Type.
Run them against the staging environment and summarize any failures.
L’agent lit chaque schéma, valide sa charge utile et ensuite seulement écrit :
apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create --file endpoint.json
apidog endpoint create --project <projectId> --file endpoint.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <projectId> --file case.json
apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json
Le endpoint.json qu’il écrit définit "method": "query", que le schéma endpoint-create de la CLI liste aux côtés de get, post et des méthodes WebDAV. Ajoutez --upload-report pour voir l’exécution dans l’application Apidog. La même commande apidog run avec -r junit s’intègre à la CI ; consultez comment exécuter des tests API en CI avec apidog run et comment utiliser l’Apidog CLI dans Claude Code. Le forfait gratuit d’Apidog couvre jusqu’à 4 utilisateurs.
FAQ
La méthode HTTP QUERY est-elle une norme officielle ? Oui. La RFC 10008 est une RFC de type Standards Track, Proposed Standard, publiée en juin 2026, et l’IANA répertorie QUERY dans le registre des méthodes HTTP comme sûre et idempotente.
QUERY est-elle simplement GET avec un corps ? Presque, mais elle est mieux définie. La RFC 9110 ne donne aucune sémantique à un corps de GET, donc les intermédiaires peuvent l’ignorer ou le rejeter. QUERY fait du corps la requête, exige un Content-Type et intègre le corps à la clé de cache.
Quand dois-je utiliser QUERY plutôt que POST ? Utilisez QUERY pour toute recherche ou tout filtre en lecture seule trop volumineux ou trop sensible pour une URL. Réservez POST aux requêtes qui créent ou modifient quelque chose.
Les navigateurs peuvent-ils envoyer des requêtes QUERY ? Oui, via fetch avec une méthode personnalisée. Les requêtes QUERY inter-origine nécessitent toujours un preflight CORS, donc votre serveur doit autoriser la méthode.
Les réponses QUERY sont-elles mises en cache ? Elles peuvent l’être. Les caches doivent inclure le corps de la requête et ses métadonnées dans la clé de cache. De nombreux CDN et proxys ne le font pas encore, alors vérifiez le vôtre ou renvoyez un URI Location que les clients peuvent GET.
OpenAPI prend-il en charge QUERY ? OpenAPI 3.2 ajoute un champ query à l’objet Path Item pour les opérations QUERY, ce qui vous permet de les documenter sans extensions.
