Proposal: Support for the HTTP QUERY method (RFC 10008)

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 into HTTP_METHODS), which also enables request.query? and the :query symbol lookup.
  • Add a query routing helper alongside get/post/… in HttpHelpers (match via: :query already works once recognized). This also makes the auto-generated Allow header advertise QUERY, matching the RFC’s OPTIONS discovery example (Allow: GET, QUERY, OPTIONS, HEAD).
  • Add a query verb 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)

5 Likes