Back openDesk Edu for a sovereign, open-source education — every vote counts.
Vote nowSave products you love by clicking the heart icon.
Das letzte Mal, dass das HTTP-Methodenregister gewachsen ist, war im Jahr 2010, als PATCH (RFC 5789) eingeführt wurde, um das Problem der Teilaktualisierungen (Partial Updates) zu lösen. Davor muss man bis zur ursprünglichen HTTP/1.1-Spezifikation von 1997 zurückgehen, um den Kernsatz zu finden: GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT. Fast drei Jahrzehnte lang waren API-Designer gezwungen, reale Anwendungsfälle in einen Methodensatz zu pressen, der nie für moderne, abfrageintensive Workloads mit Request-Body konzipiert wurde.
Das ändert sich mit RFC 10008, der im Juni 2026 auf dem IETF Standards Track veröffentlicht wurde. Verfasst von Julian Reschke (greenbytes), James M. Snell (Cloudflare) und Mike Bishop (Akamai), schließt die QUERY-Methode eine Lücke, die seit dem Einsatz der ersten RESTful API eine Quelle architektonischer Reibung darstellt.
Jeder API-Designer kennt dieses Szenario: Man muss eine komplexe Abfrage an einen Server senden – ein GraphQL-Dokument, eine Elasticsearch-Query-DSL, ein SPARQL-Triple-Pattern oder einen CouchDB _find Selector. Diese Payloads sind zu groß für einen GET-Query-Parameter und enthalten Sonderzeichen, die das URL-Encoding mühsam machen. Die Optionen waren bisher:
| Methode | Überträgt Body | Safe | Idempotent | Cachebar |
|---|---|---|---|---|
| GET | Nein | Ja | Ja | Ja |
| POST | Ja | Nein | Nein | Nur über expliziten Header |
| QUERY | Ja | Ja | Ja | Ja (mit Body im Key) |
„Safe“ bedeutet, dass die Anfrage keine Nebenwirkungen verursacht. „Idempotent“ bedeutet, dass N identische Anfragen denselben Serverzustand erzeugen. GET ist beides – kann aber keinen Body übertragen. POST kann einen Body übertragen, ist aber weder safe noch idempotent, was die Retry-Logik, das Caching durch Intermediäre und das Preloading beeinträchtigt. Dies ist kein Nischenproblem.
GraphQL-Implementierungen versenden jede Abfrage als POST, da das Abfragedokument ein JSON-String ist, der im Request-Body liegt. Das bedeutet, dass GraphQL-Abfragen nicht von HTTP-Intermediären gecacht, nicht sicher wiederholt und nicht von Browsern oder CDNs vorab geladen (prefetch) werden können. Die GraphQL-Community weiß seit langem, dass dies suboptimal ist – der empfohlene Workaround besteht darin, einen Hash der Abfrage zu berechnen und diesen als GET-Parameter zu senden, was jedoch serverseitige Unterstützung erfordert und die selbstbeschreibende Natur der Anfrage zerstört.
Elasticsearch-Nutzer haben mit derselben Spannung zu kämpfen: Jede Suchabfrage ist ein POST an _search. Dasselbe gilt für SPARQL-Endpunkte, OData-Services und CouchDB-Clients. Die QUERY-Methode eliminiert diese Kategorie von Workarounds vollständig.
RFC 10008 definiert QUERY als eine Methode, die:
Content-Type Header an, welche Abfragesprache er sprichtDer Request-Body enthält den Abfrageausdruck. Der Server interpretiert diesen gemäß dem Media-Type in Content-Type und gibt eine Repräsentation der Ergebnisse zurück. Die Antwort kann jeder HTTP-Statuscode sein, der für die Abfrage angemessen ist – 200 für ein erfolgreiches Ergebnisset, 204 für leere Ergebnisse, 404, wenn die Abfrage eine Ressource anspricht, die nicht existiert.
Eine der kniffligsten Designfragen, die der RFC lösen musste, war das Caching. Eine QUERY an /api/search mit {"term": "kubernetes"} sollte eine andere gecachte Antwort erzeugen als dieselbe URL mit {"term": "rust"}. In HTTP ist der Cache-Key für GET-Anfragen allein die URL. Für QUERY MUSS der Cache-Key den Request-Body enthalten.
Der RFC spezifiziert, dass Caches den Cache-Key als URL plus Body-Inhalt berechnen. Vary-Header und Cache-Control Direktiven gelten wie gewohnt. Intermediäre Caches, die keinen Body-im-Cache-Key unterstützen, DÜRFEN QUERY-Antworten NICHT cachen. Dies ist eine erhebliche Implementierungshürde für bestehende CDNs und Reverse Proxies – dazu mehr unten.
Server, die QUERY unterstützen, kündigen dies über den Accept-Query Response-Header (oder eine OPTIONS-Antwort) an. Dieser Header listet die Abfrage-Media-Types auf, die der Server versteht:
Accept-Query: application/graphql, application/json
Clients können OPTIONS verwenden, um herauszufinden, ob ein Server QUERY unterstützt, bevor sie eine potenziell teure Anfrage senden. Dies spiegelt wider, wie Allow für die Methodenerkennung funktioniert.
Wenn Sie mit der WebDAV-Welt vertraut sind, erinnern Sie sich vielleicht an die SEARCH-Methode, die in RFC 5323 definiert wurde. Sie hatte im Wesentlichen dieselbe Semantik – safe, idempotent, überträgt einen Body. Warum also eine neue Methode?
Die Working Group zog SEARCH in Betracht, lehnte es aber letztendlich aus zwei Gründen ab:
Der Konsens war, dass ein sauberer Neuanfang vor einer Anpassung von SEARCH für das moderne Web vorzuziehen sei.
Die Einführung erfolgt schneller als bei jeder bisherigen HTTP-Methode. So sieht der Stand im Juli 2026 aus:
| Runtime | Unterstützung | Notizen |
|---|---|---|
| Node.js 21.7+ | Nativ über http Modul | Im Core enthalten – kein Polyfill nötig |
| curl | --request QUERY | Volle Unterstützung seit 8.10 |
| Rust reqwest | Benutzerdefinierte Methode via Method::from_bytes(b"QUERY") | Funktioniert mit jeder HTTP-Methode |
| Python httpx | client.request("QUERY", url, content=body) | Unterstützt über generische Methoden-API |
| Go net/http | Keine spezielle Konstante, aber http.NewRequest("QUERY", url, body) | Funktioniert mit jedem Methoden-String |
| Java Apache HttpClient 5.4+ | HttpMethods.QUERY | First-Class-Konstante hinzugefügt |
| Ruby Net::HTTP | Net::HTTP.new(uri).request_post(uri, body, "method" => "QUERY") | Über generischen Methoden-Override |
| Plattform | Unterstützung | Notizen |
|---|---|---|
| Go net/http | Standard-Handler — Match auf r.Method == "QUERY" | Trivial zu implementieren |
| Node.js http | request.method === 'QUERY' | Wie jede andere Methode |
| Express.js | app.query('/path', handler) | Express 5.x experimentell |
| Python Starlette/FastAPI | Über generischen Route-Handler | Noch kein dedizierter Decorator |
| Rust actix-web | guard::Method("QUERY") | Manueller Guard erforderlich |
| Laravel 12 | Route::query('/search', ...) | Erstes Framework mit dediziertem Routing |
Laravel verdient eine besondere Erwähnung – Taylor Otwell implementierte Route::query() in Laravel 12 innerhalb weniger Wochen nach der RFC-Veröffentlichung und machte es damit zum ersten großen Framework, das ein First-Class-Routing für die QUERY-Methode bietet.
Hier wird die Geschichte kompliziert:
| Proxy | Status |
|---|---|
| nginx | Reicht unverändert durch — unterstützt unbekannte Methoden standardmäßig |
| Caddy | In v2.10 für query-cache-key gepatcht |
| Apache httpd | Patch in 2.5-dev verfügbar |
| CloudFront | Blockiert QUERY — wird als nicht erkannte Methode angesehen |
| Akamai | Blockiert QUERY — erfordert explizite Änderung der Methoden-Allowlist |
| Cloudflare | Reicht durch, ignoriert aber den Body im Cache-Key — effektiv nicht cachebar |
| Varnish | Benötigt benutzerdefiniertes VCL für Body-basierten Cache-Key |
Wenn Sie CloudFront oder Akamai nutzen, können Sie QUERY-Anfragen heute nicht über das CDN bedienen. Dies ist das größte Hindernis für die Einführung. Die RFC-Autoren arbeiten aktiv mit CDN-Anbietern zusammen, und Cloudflare hat signalisiert, dass die Unterstützung noch vor Ende 2026 erscheinen wird.
import http from "node:http";
const queryBody = JSON.stringify({ query: "{ users { name email } }" });
const options = {
hostname: "api.example.com",
port: 443,
path: "/graphql",
method: "QUERY",
headers: {
"Content-Type": "application/graphql",
"Content-Length": Buffer.byteLength(queryBody),
},
};
const req = http.request(options, (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => console.log(data));
});
req.write(queryBody);
req.end();
curl --request QUERY \
--header 'Content-Type: application/json' \
--data '{"query": {"term": "kubernetes", "limit": 10}}' \
https://api.example.com/search
import http from "node:http";
const server = http.createServer((req, res) => {
if (req.method === "QUERY" && req.url === "/search") {
let body = "";
req.on("data", (chunk) => (body += chunk));
req.on("end", () => {
const query = JSON.parse(body);
// Execute search against index
const results = searchIndex(query.term, query.limit);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(results));
});
return;
}
// Handle other methods...
});
server.listen(3000);
package main
import (
"encoding/json"
"net/http"
)
type Query struct {
Term string `json:"term"`
Limit int `json:"limit"`
}
func queryHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "QUERY" {
http.Error(w, "method not allowed", 405)
return
}
var q Query
json.NewDecoder(r.Body).Decode(&q)
results := search(q.Term, q.Limit)
json.NewEncoder(w).Encode(results)
}
func main() {
http.HandleFunc("/api/search", queryHandler)
http.ListenAndServe(":8080", nil)
}
Dies ist der entscheidende Anwendungsfall. Ein GraphQL-Endpunkt sendet heute jede Abfrage als POST. Mit QUERY:
Ein GraphQL-Server, der Accept-Query: application/graphql ankündigt, signalisiert Clients: „Hier können Sie schreibgeschützte Abfragen senden.“ Das Framework kann QUERY-Anfragen auf der Transportebene an den Query-Executor und POST-Anfragen an den Mutation-Executor routen, wodurch eine ganze Klasse von Bugs eliminiert wird, bei denen eine Abfrage versehentlich einen Schreibvorgang auslöst.
Elasticsearch, Algolia, Meilisearch und jeder benutzerdefinierte Such-Endpunkt profitieren sofort. Suchen sind von Natur aus sicher und idempotent — man stellt dem Index eine Frage. QUERY macht dies im Protokoll explizit.
Triple-Stores und OData-Dienste haben schon immer komplexe Query-Ausdrücke im Body übertragen. Insbesondere SPARQL-Endpunkte litten unter den Längenbeschränkungen von GET-URLs (das Standard-SPARQL-Protokoll über GET kodiert die gesamte Abfrage in der URL). QUERY eliminiert diese Einschränkung vollständig.
_findCouchDB ist ein Paradebeispiel für Workarounds bei Methoden. Sein _find-Endpunkt verwendet POST mit einem JSON-Selektor, und die CouchDB-Community wünscht sich schon lange eine dedizierte Methode. Tatsächlich hat das CouchDB-Team bereits 2015 ? als HTTP-Methode registriert und auf einen Standard gewartet — QUERY ist die Formalisierung, auf die sie gewartet haben.
QUERY ist kein einfacher Drop-in-Ersatz für bestehende Muster. Hier sind die Überlegungen vor der Einführung:
CDN-Kompatibilität — Wenn Sie sich auf CloudFront oder Akamai verlassen, können Sie QUERY derzeit nicht über diese Dienste nutzen. Planen Sie einen Upgrade-Pfad ein, bei dem QUERY an Ihrem Origin oder hinter einem Proxy terminiert wird, der dies unterstützt.
Framework-Support — Die meisten Web-Frameworks verfügen noch über kein dediziertes QUERY-Routing. Sie können dies weiterhin über generisches Method-Matching (r.Method == "QUERY") handhaben, verlieren aber die Ergonomie, die POST und GET bieten. Dies wird sich in den nächsten 12 Monaten verbessern.
Bestehende Clients — Alte Clients werden weiterhin POST an Ihre Query-Endpunkte senden. Sie müssen während einer Übergangsphase sowohl QUERY als auch POST unterstützen. Der RFC empfiehlt dies explizit — Server SOLLTEN weiterhin POST als Fallback für Query-Operationen akzeptieren.
Caching-Infrastruktur — Wenn Sie Antworten cachen, stellen Sie sicher, dass Ihre Cache-Ebene body-in-cache-key unterstützt. Varnish erfordert benutzerdefiniertes VCL. nginx benötigt die proxy_cache_key-Direktive, um den Body einzubeziehen. Redis-basierte Caches müssen den Body manuell hashen.
Security Appliances — WAFs, API-Gateways und Intrusion-Detection-Systeme erkennen QUERY möglicherweise nicht. Überprüfen Sie Ihre Security-Tools auf die Unterstützung von Method-Allowlists und fügen Sie QUERY explizit hinzu.
RFC 10008 ist die erste neue HTTP-Methode seit sechzehn Jahren, aber sie wird nicht die letzte sein. Die HTTP Working Group hat die Arbeit an der Methodenregistrierung wieder aufgenommen, mit dem Ziel, Muster zu formalisieren, die organisch entstanden sind – WebSocket-Upgrade-Semantiken, Event-Stream-Subscription-Muster und idempotente Batch-Operationen werden derzeit alle diskutiert.
Für API-Designer bietet QUERY etwas, das seit der ersten Standardisierung von HTTP fehlte: eine Methode, die gleichzeitig safe, idempotent, body-carrying und cacheable ist. Dass es dreißig Jahre dauerte, bis sie eingeführt wurde, sagt weniger über die Schwierigkeit des Problems aus als vielmehr darüber, wie kreativ die Web-Community bei der Umgehung von Protokolllücken war. GraphQL, Elasticsearch, CouchDB, SPARQL und jede Such-API, die Sie jemals gebaut haben, verwendeten alle die falsche Methode, weil die richtige nicht existierte.
Jetzt existiert sie. Beginnen Sie damit, Accept-Query zu Ihrer OPTIONS-Antwort hinzuzufügen. Implementieren Sie das QUERY-Routing neben Ihren bestehenden POST-Handlern. Überprüfen Sie, ob Ihr CDN dies zulässt. Und wenn Sie das nächste Mal eine API entwerfen, die dem Server eine Frage stellt, verwenden Sie die Methode, die genau für diesen Zweck entwickelt wurde.