Summary
RFC 10008 (The HTTP QUERY Method) was published as a Proposed Standard in June 2026, and QUERY is now registered in the IANA HTTP Method Registry as safe + idempotent. QUERY is effectively “GET with a body”: the query is carried in the request content like POST, but the method is explicitly safe and idempotent, so responses are cacheable and requests are safely retryable. It targets read/query endpoints whose input is too large or too structured for the URL (GraphQL, JSON-RPC, complex search).
I’d like to add first-class support for QUERY to Action Pack and I’m happy to do the implementation. I want to align on one design decision (CSRF) before opening a PR.
Current state
ActionDispatch::Request#check_method rejects QUERY today since it isn’t in
the HTTP_METHODS allowlist in action_dispatch/http/request.rb, so a QUERY
request raises ActionController::UnknownHttpMethod (→ 405) before reaching a
controller. Puma/Rack pass the verb through fine; the gate is purely in
Action Pack. Note we already recognize SEARCH (RFC 5323), so a query-style
verb in the allowlist isn’t new ground.
Proposed scope (v1)
- Register the method (e.g.
RFC10008 = %w(QUERY)folded intoHTTP_METHODS), which also enablesrequest.query?and the:querysymbol lookup. - Add a
queryrouting helper alongsideget/post/… inHttpHelpers(match via: :queryalready works once recognized). This also makes the auto-generatedAllowheader advertise QUERY, matching the RFC’s OPTIONS discovery example (Allow: GET, QUERY, OPTIONS, HEAD). - Add a
queryverb helper to the integration/functional test helpers. - Classify QUERY as safe in
safe_method?(the predicate recently added per RFC 9110), since RFC 10008 defines it as safe + idempotent. - CHANGELOG + the HTTP method list in the guides.
Out of scope for v1 (happy to follow up separately): the Accept-Query
response header, content-negotiation status semantics (415/422), and
cache-key handling — these are app/intermediary concerns, not core verb
support. The RFC’s “MUST fail if Content-Type is missing/inconsistent” is
also left to the application, consistent with how Rails treats other methods.
The decision I’d like input on: CSRF
If QUERY is treated like GET for CSRF (i.e. no token required), I believe that’s correct and not a regression:
- No HTML form can emit a QUERY request (forms only do GET/POST), so the classic forged-form vector doesn’t exist.
- A cross-origin JS QUERY isn’t CORS-safelisted, so it always triggers a preflight (per RFC 10008 §4 and Fetch).
- QUERY is safe + idempotent by definition, so treating it like GET (which Rails already leaves unprotected) is the consistent choice.
Implementation note: adding QUERY to safe_method? alone wouldn’t change CSRF
behavior, since verified_request? checks get?/head? specifically. So
making QUERY token-free would mean explicitly adding request.query? there
too. I’d prefer that, but since it touches security behavior I want a steer
before baking it in. The conservative alternative is to require a token
(treat QUERY as unsafe for CSRF purposes) and relax later.
If this direction sounds reasonable, I’ll open a PR with the v1 scope above plus tests. Thanks!
— Muhammet Dilmaç (@MuhammetDilmac)