• Skip to primary navigation
  • Skip to main content
  • Skip to footer

Codemotion Magazine

We code the future. Together

  • Discover
    • Events
    • Community
    • Partners
    • Become a partner
    • Hackathons
  • Magazine
    • Backend
    • Dev community
    • Carriere tech
    • Intelligenza artificiale
    • Interviste
    • Frontend
    • DevOps/Cloud
    • Linguaggi di programmazione
    • Soft Skill
  • Talent
    • Discover Talent
    • Jobs
    • Manifesto
  • Companies
  • For Business
    • EN
    • IT
    • ES
  • Sign in
ads

Matteo BaccanLuglio 29, 2026 10 min di lettura

HTTP QUERY: il metodo che mancava tra GET e POST

Backend
facebooktwitterlinkedinreddit

Per quasi trent’anni il Web ha convissuto con un paradosso semantico che chiunque sviluppi per il backend conosce bene: come si esegue un’interrogazione complessa, voluminosa o contenente dati sensibili, se l’unico metodo “sicuro” a disposizione non prevede un corpo della richiesta?

Pensiamo a quando dobbiamo inviare una query di ricerca strutturata con filtri annidati, ordinamenti e paginazioni multidimensionali. O magari una query SQL, un’espressione JSONPath o un documento GraphQL.

Recommended article
platform engineering
Marzo 17, 2026

Che cos’è il Platform Engineering

Giorgio Delle Grottaglie

Backend

Il pensiero del programmatore ingenuo è: aggiungo un parametro “q” all’URI e lo invio con GET, cosa sarà mai.

Poi col tempo i parametri diventano 10, 100, 1000 e il programma implode. Questo succede perché il proxy che attraversa il firewall, memorizza i dati su Redis e fa bilanciamento del carico ha un limite di 2048 caratteri per l’URI. Oppure succede perché il firewall registra in chiaro l’URI e lo invia a un SIEM, esponendo dati sensibili come filtri di ricerca o credenziali.

Infilare tutto questo in un URI con il classico metodo GET ci espone a limiti fisici di trasporto e a seri rischi di sicurezza.

Cosa fa invece chi vuole un minimo di sicurezza? Usa solo richieste POST: tutto rimane celato nel corpo della richiesta e non importa se distruggiamo la semantica, impediamo il caching o portiamo ai suicidio il nostro professore di sistemi, l’importante è che la sicurezza sia salva.

Ho lavorato con un progetto alla cui base c’è questa logica: rozza, ma efficace.

L’RFC 10008, pubblicato dall’IETF nel giugno 2026 e classificato come Proposed Standard, risolve finalmente questo dilemma introducendo il metodo QUERY. Proviamo a capire se ne vale la pena o se è arrivato troppo tardi sulle nostre scrivanie. Una cosa infatti è lo standard, un’altra è la sua adozione, per la quale ci vorranno anni. Si tratta di aggiornare linguaggi, framework, librerie, proxy, bilanciatori, CDN, WAF e browser.

Questo nuovo verbo combina la garanzia semantica di sicurezza e idempotenza (tipiche di GET) con la capacità strutturale di trasportare un payload esteso nel corpo della richiesta (tipica di POST).

In questo articolo esploreremo la genesi del metodo QUERY, come funziona sotto il cofano, le sue implicazioni su caching e sicurezza, e come possiamo implementarlo oggi nei nostri backend (o almeno in futuro, quando l’ecosistema smetterà di rifiutare la richiesta con un desolante HTTP/1.0 405 Method Not Allowed).

QUERY trasporta l'interrogazione nel corpo della richiesta, superando i limiti di GET, ma con una semantica di sicurezza che POST non può garantire.

La genesi di uno standard: AUTH48 e il ruolo dell’IETF

Il metodo QUERY non è nato dall’oggi al domani. È il frutto del lavoro del gruppo HTTPbis dell’IETF, redatto da nomi noti dell’ingegneria dei protocolli come Julian Reschke (greenbytes), James M. Snell (Cloudflare) e Mike Bishop (Akamai).

Un dettaglio interessante riguarda la fase finale di revisione dello standard, nota come “AUTH48”. Per la prima volta, l’RFC Production Center (RPC) ha utilizzato un progetto pilota basato su repository GitHub anziché sui tradizionali e lenti flussi di email (https://github.com/rfc-editor-drafts/FinalReview-rfc10008).

Questo ha permesso una tracciabilità granulare delle modifiche redazionali, accelerando il rilascio di uno standard che promette di cambiare le regole del gioco.

Il problema: i limiti fisici e semantici di GET e POST

Per apprezzare il valore di QUERY, dobbiamo guardare da vicino le limitazioni che ci hanno tormentato per decenni.

I limiti di GET: tra URI troppo lunghi e log in chiaro

Con GET la query vive interamente nell’URI. Anche se l’RFC 9110 raccomanda che l’infrastruttura supporti URI di almeno 8000 ottetti, nella realtà ci scontriamo con firewall, load balancer e CDN non coordinati che applicano limiti inferiori e variabili. Chi lavora in ambito enterprise sa bene che 2048 caratteri è un limite comune, mentre alcuni proxy più vecchi si fermano a 1024.

Il superamento di questi limiti genera errori come “414 URI Too Long”, sempre difficili da diagnosticare, soprattutto quando il problema si manifesta solo in ambienti di produzione con traffico reale.

C’è poi un problema critico di privacy: gli URI vengono registrati in chiaro nei log dei server. Una semplice ricerca tramite grep può estrarre una grande quantità di dati sensibili con lo sforzo minimo.

Ricordo ancora quando, durante una delle mie prime analisi di sicurezza dei log per un grande operatore nazionale di telecomunicazioni, saltai letteralmente sulla sedia: guardandoli, mi resi conto che tutte le login di un certo applicativo avvenivano in GET anziché in POST. Le password di migliaia di utenti erano lì, scritte in chiaro nei file di testo del server web.

Oltre a questo, anche se il fenomeno è molto più mitigato rispetto al passato, gli header “Referer” verso siti terzi possono trasportare dati che dovevano rimanere segregati nel server di origine.

Per questi motivi GET ha un peccato originale: non è adatto a trasportare dati sensibili, eppure è l’unico metodo sicuro e idempotente disponibile.

Infine, memorizzare in cache queste richieste è inefficiente. Qualsiasi variazione sintattica nell’ordine dei parametri o nella codifica dei caratteri invalida la cache, trasformando query semanticamente identiche in risorse distinte.

Il ripiego su POST: la perdita del contratto semantico

Per aggirare i limiti di GET, la prassi comune è stata quella di abusare di POST, spostando la query nel body: un approccio semplice, ma con conseguenze semantiche significative.

In questo modo non abbiamo più problemi di spazio nell’URI e i log rimangono puliti (è vero che si può abilitare il logging del body, ma di default non è attivo), ma il meccanismo rompe le garanzie del protocollo. Il metodo POST non è né sicuro né idempotente per definizione.

Di conseguenza, gli intermediari coinvolti nel trasporto di una richiesta POST, non sapendo se stia leggendo dati o modificando un database, evitano di reinviare i dati (come avviene con i browser) o di effettuare il caching (come avviene con le CDN).

I precursori WebDAV e perché evitare SEARCH o REPORT

Chi ha più esperienza o qualche capello grigio ricorderà sicuramente i tentativi fatti con WebDAV e metodi come “SEARCH” o “PROPFIND”. C’è ancora chi pensa che WebDAV sia una soluzione perfetta, ma forse dovrebbe ricredersi dopo questa specifica e su come abbia volutamente ignorato i metodi WebDAV per crearne uno completamente nuovo.

Si è deciso però di non riciclare quei metodi, che nascevano legati a doppio filo con il Content-Type “application/xml”, ma di ripartire da zero.

QUERY nasce così agnostico, non legato a un formato specifico, in modo che chi lo utilizza possa gestire in autonomia il proprio “Content-Type”.

Stiamo quindi prendendo le cose positive di GET: sicurezza, idempotenza e caching, e vi si aggiunge il corpo della richiesta POST.

Negoziazione del contenuto e codici di errore

Ragionando con il “Content-Type” iniziano ad arrivare i primi vincoli: se un client chiede un formato “application/xml” e il server ha un contenuto diverso, la richiesta viene rigettata. Lo stesso avviene se il client non indica in modo esplicito questo dato.

Lo standard definisce in modo rigoroso questo passaggio all’interno della sezione “2.1 Media Types and Content Negotiation”:

  • 400 Bad Request: se il media type è assente o malformato.
  • 415 Unsupported Media Type: se il formato di query non è supportato dall’endpoint.
  • 406 Not Acceptable: se il formato richiesto in “Accept” non è disponibile.
  • 422 Unprocessable Content: se la query è sintatticamente valida ma logicamente non elaborabile (es. fa riferimento a una tabella o a un campo inesistente).

Discovery e l’header Accept-Query

Come fa un client a sapere quali formati di query sono accettati da un endpoint? L’RFC 10008 introduce l’header di risposta “Accept-Query”.

Questo header adotta le specifiche degli “Structured Fields” (RFC 9651). Essendo una lista formattata di token, permette ai client di fare il parsing in modo standard, senza regex complesse:

Accept-Query: "application/jsonpath", "application/sql"Code language: JavaScript (javascript)

Un client può scoprire le capacità del server in due modi:

  • Preventivo: invia una richiesta “OPTIONS” o “HEAD” e legge gli header “Allow” (che include QUERY) e “Accept-Query”.
  • Aggressivo: invia direttamente una richiesta “QUERY”. Se il server non supporta quel formato, risponde con “415 Unsupported Media Type” e include “Accept-Query” per indicare i formati ammessi.

Chiaramente se c’è la possibilità di concordare il formato l’approccio è migliore perché evita round-trip aggiuntivi, ma non è sempre possibile.

Il concetto di “risorsa equivalente”

Per rispettare il principio del Web secondo cui ogni risorsa deve avere un URI, l’RFC introduce la “risorsa equivalente”: una risorsa concettuale (accessibile in GET) che rappresenta il risultato di una specifica richiesta QUERY più i suoi metadati.

Il server può materializzare questa risorsa fornendo due header distinti nella risposta:

  • Location: punta alla query viva e ripetibile. Il client può fare una “GET” a questo URI per ripetere l’interrogazione e ottenere dati aggiornati. Questo URI può essere temporaneo: se scade, il client torna semplicemente a inviare la richiesta “QUERY” completa.
  • Content-Location: identifica uno snapshot statico e storicizzato dei risultati in quel preciso momento.

Gestione dei redirect e richieste condizionali

A differenza di POST, dove i redirect “301” o “302” portavano spesso i browser a trasformare la richiesta in una “GET” (perdendo il body), con QUERY il client deve mantenere lo stesso metodo e body verso il nuovo URI per i codici “301”, “302”, “307” e “308”.

Non si tratta di un errore: il client deve essere consapevole che la risorsa è stata spostata e che la query va ripetuta nello stesso formato.

Solo il codice “303 See Other” impone il passaggio a una GET. Questo è utile per le query asincrone molto onerose: il server risponde subito con “303” e un header “Location”, dicendo al client di recuperare il risultato pronto tramite una “GET” successiva.

Per le richieste condizionali, il client può inviare intestazioni come “If-Modified-Since” basandosi sui timestamp ricevuti in precedenza. Se i dati sottostanti non sono cambiati, il server risponde con un leggero “304 Not Modified”, risparmiando banda preziosa.

Ingegneria dell’edge network: il caching basato sul corpo

La parte più sfidante di QUERY è sicuramente la gestione della cache. Per i reverse proxy o le CDN attuali, abituate a fare cache basandosi solo sulla parte di intestazione, si tratta di introdurre dei meccanismi in grado di tener conto anche del corpo della richiesta.

Questo significa che il sistema di cache deve calcolare un hash del corpo della richiesta per identificare le chiamate ripetute. Tale operazione, a seconda della dimensione del payload, può introdurre una latenza proporzionale ai dati inviati.

La normalizzazione

Visti i problemi relativi all’ordine dei parametri e all’inefficienza della cache, l’RFC specifica:

Per migliorare l'efficienza della cache, le cache POSSONO rimuovere prima le differenze semanticamente insignificanti dal contenuto della richiesta e dai metadati correlati

Questo è un aspetto importante per migliorare l’efficienza della cache, ma introduce un rischio: se il parser del proxy e quello del server di origine normalizzano i dati in modo differente, si rischia il fenomeno dei “Parser Differentials”: la cache potrebbe servire un falso positivo (dati di una query per un’altra).

Nel caso in cui ci sia una catena di processi intermedi che rischia di portare a questa deriva, l’intestazione prevista è:

Cache-Control: no-transformCode language: HTTP (http)

A essere onesti, l’header no-transform rappresenta la paura viscerale di chi ha disegnato questa specifica. Probabilmente ha passato le notti insonni a fare il debug di una cache sbagliata nei modi più subdoli possibili e alla fine si è arreso, introducendo un parametro di non alterabilità proprio all’interno di una specifica che teoricamente ne dichiarava la possibilità.

Questo header finirà per essere adottato in molti scenari reali proprio per evitare qualsiasi disallineamento imprevedibile tra parser diversi.

Sicurezza, privacy e preflight CORS

Fino a qui sembrano tutte cose bellissime, ma l’introduzione di un nuovo metodo HTTP ha delle implicazioni importanti sulla sicurezza e sulla privacy.

  • WAF Blind Spots (Punti Ciechi): molti Web Application Firewall tradizionali analizzano il body delle richieste solo per metodi non sicuri (POST, PUT, PATCH). Vedendo un metodo “safe” come QUERY, potrebbero saltare l’ispezione profonda, consentendo a payload nocivi (SQL Injection, XSS) di raggiungere il backend. I team di sicurezza devono aggiornare i WAF e impostare regole per monitorare attentamente il traffico QUERY.
  • Controlli anti-CSRF: se gli endpoint QUERY vengono implementati male e producono effetti collaterali sul database (per esempio usati come fossero delle POST), i middleware anti-CSRF potrebbero ignorarli ritenendoli sicuri, esponendo l’applicazione a vulnerabilità.
  • CORS Preflight: QUERY non è un metodo “safelisted” nelle specifiche Fetch di WHATWG. Le richieste cross-origin richiederanno sempre una richiesta di preflight “OPTIONS”, raddoppiando il round-trip di rete. È fondamentale configurare opportunamente l’header “Access-Control-Max-Age” per memorizzare in cache il preflight ed evitare colli di bottiglia prestazionali.
  • Vantaggi per la privacy: spostando i parametri sensibili dall’URI al corpo opaco della richiesta, QUERY previene fughe di dati nei log dei server e nelle cronologie dei browser, allineandosi perfettamente al principio di minimizzazione dei dati del GDPR.

La svolta per GraphQL e headless commerce

GraphQL ha vissuto per anni un dilemma di caching. Essendo le sue query troppo lunghe per GET, sono state storicamente inviate via POST, disabilitando le cache edge. Gli ingegneri hanno dovuto inventare soluzioni complesse come le query persistenti per ripristinare il caching con GET.

Con QUERY, i client GraphQL possono inviare query complete specificando “application/graphql”, aumentando le prestazioni e riducendo la complessità dell’applicazione.

Supporto nei backend

  • Node.js: il parser C++ integrato nei recenti rami di Node (21.x e 22+) supporta nativamente QUERY. Framework come Fastify permettono il routing esplicito con il flag { hasBody: true }.
  • Go: il pacchetto “net/http” gestisce i metodi come stringhe, e il router introdotto in Go 1.22 supporta già il routing di QUERY out-of-the-box.
  • OpenAPI 3.2+: supporta ufficialmente la definizione e la documentazione del metodo QUERY.

E i browser?

Le discussioni presso il WHATWG (issue #12594) stanno definendo il supporto per <form method="query">. Quando questo verrà implementato, potremo finalmente aggiornare i moduli di ricerca web dicendo addio all’odioso avviso di “conferma reinvio modulo” al refresh della pagina.

Un protocollo finalmente maturo?

Il metodo QUERY non è una semplice aggiunta sintattica. Risolve un’incongruenza strutturale che ci portiamo dietro dagli albori del web.

Restituendo dignità semantica alle letture complesse, ci permette di costruire API più pulite, sicure ed efficienti, liberandoci dall’obbligo di barattare la scalabilità del caching con la privacy e lo spazio di trasporto.

La transizione richiederà tempo, soprattutto per l’adeguamento dei client web e dei sistemi di sicurezza di rete. Ma la strada è tracciata: interrogare non è modificare, e da oggi il protocollo HTTP lo sa.

RFC 10008 – The HTTP QUERY Method
HTTPbis
WHATWG

Related Posts

La signature chain: garanzia di autenticità, integrità e sequenzialità nei documenti digitali

Antonio Musarra
Giugno 3, 2025

VanillaCreamJS: JavaScript con i superpoteri

Riccardo Degni
Maggio 28, 2025

Come risolvere il dual write problem nei sistemi distribuiti

Codemotion
Maggio 22, 2025

Top 10 piattaforme online per fare pratica con Python

Lucilla Tomassi
Maggio 13, 2025
Share on:facebooktwitterlinkedinreddit
Matteo Baccan
Matteo Baccan è un ingegnere del software e formatore professionista con oltre 30 anni di esperienza nel settore IT. Ha lavorato per diverse aziende e organizzazioni, occupandosi di progettazione, sviluppo, testing e gestione di applicazioni web e desktop, utilizzando vari linguaggi e tecnologie. È anche un appassionato divulgatore e insegnante di informatica, autore di numerosi articoli, libri e corsi online rivolti a tutti i livelli di competenza. Gestisce un sito internet e un canale YouTube dove condivide video tutorial, interviste, recensioni e consigli sulla programmazione. Attivo nelle community open source, partecipa regolarmente a eventi e concorsi di programmazione. Si definisce…
Federated Learning: allenare modelli senza spostare i dati
Previous Post

Footer

Discover

  • Events
  • Community
  • Partners
  • Become a partner
  • Hackathons

Magazine

  • Tech articles

Talent

  • Discover talent
  • Jobs

Companies

  • Discover companies

For Business

  • Codemotion for companies

About

  • About us
  • Become a contributor
  • Work with us
  • Contact us

Follow Us

© Copyright Codemotion srl Via Marsala, 29/H, 00185 Roma P.IVA 12392791005 | Privacy policy | Terms and conditions