Skip to content

Add support for the HTTP QUERY method (RFC 10008)#4140

Open
mo-bruno wants to merge 4 commits into
actix:mainfrom
mo-bruno:feat/query-method
Open

Add support for the HTTP QUERY method (RFC 10008)#4140
mo-bruno wants to merge 4 commits into
actix:mainfrom
mo-bruno:feat/query-method

Conversation

@mo-bruno

@mo-bruno mo-bruno commented Jul 8, 2026

Copy link
Copy Markdown

PR Type

Feature

PR Checklist

  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.
  • A changelog entry has been made for the appropriate packages.
  • Format code with the latest stable rustfmt.
  • (Team) Label with affected crates and semver status.

Overview

Adds first-class support for the HTTP QUERY method, wired exactly like the existing
PATCH method throughout routing, guards, the web:: helpers, the routing macros, the
awc client, and the test servers.

QUERY was standardized in RFC 10008
(June 2026)
and registered in the IANA HTTP Method Registry. It is safe and
idempotent like GET, but carries a request body like POST — the first new HTTP
method since PATCH (RFC 5789, 2010). Because actix-web's extractors are method-agnostic,
body extraction (web::Json, web::Bytes, …) works for QUERY handlers with no special
handling.

This is a purely additive change (new public items only) → semver-minor; no breaking
changes.

What's included

actix-web

  • guard::Query() — method guard, mirrors guard::Patch()
  • web::query() — pre-configured Route, mirrors web::patch()
  • Resource::query() — route shortcut, mirrors Resource::patch()
  • TestRequest::query() — test helper, mirrors TestRequest::patch()
  • re-export of the #[query] routing macro

actix-web-codegen

  • #[query] attribute macro, mirrors #[patch]

awc

  • Client::query() — mirrors Client::patch()

actix-test / actix-http-test

  • TestServer::query() (and actix-http-test's HTTPS TestServer::squery()) — mirror patch/spatch

Every method-convenience surface that has a patch now has a matching query, so QUERY
is a first-class method throughout.

Notes for reviewers

  • http crate version. actix-web currently pins http 0.2, which has no
    Method::QUERY associated constant (that constant only exists in http 1.x). This PR
    therefore constructs the method with Method::from_bytes(b"QUERY").unwrap() and leaves a
    TODO to switch to Method::QUERY once the dependency is bumped. This mirrors the
    existing Method::from_bytes(...).unwrap() pattern already used in actix-web-codegen
    for custom methods. This PR does not bump http — that is tracked separately in
    Updating to HTTP crate v1 #3384. No new dependencies are added.
  • actix-http. No change needed: actix-http re-exports http::Method and has no
    local method enum/constant list, so there is nothing to mirror there.
  • Scope. Minimal and mechanical — every change mirrors an existing PATCH site. No
    unrelated refactoring.

Tests

  • guard::Query() matches a QUERY request and rejects a GET.
  • A web::query() route returns 200 for QUERY and 405 (Allow: QUERY) for other methods.
  • A QUERY handler reads and echoes a JSON body (proves body-carrying works).
  • #[query] macro integration test mirrors the existing #[patch] test (test_body).
  • awc::Client::query() builds a request whose method is QUERY.
  • Round-trip tests for each test-server helper against a live server: actix_test::TestServer::query()
    (body echo through a web::query() route), actix_http_test::TestServer::query() (plaintext HTTP/1),
    and actix_http_test::TestServer::squery() (rustls; asserts the request arrives as QUERY over HTTP/2).

Verification

Local, matching the project's CI gates:

  • cargo +nightly fmt --all -- --check — clean.
  • cargo clippy --workspace --all-targets ... -D clippy::todo -D clippy::dbg_macro — 0 warnings.
  • cargo +nightly doc --no-deps ... -D warnings — my [QUERY] intra-doc link resolves; no new warnings.
  • just check-min / just check-default (cargo hack --workspace check [--no-default-features]) — pass.
  • cargo +1.88 (MSRV) check — pass.
  • Tests pass across actix-web, actix-web-codegen, awc, actix-test, actix-http-test
    (incl. doctests and awc integration/TLS tests), 0 failed.

mo-bruno and others added 2 commits July 7, 2026 19:05
QUERY (RFC 10008, June 2026; registered in the IANA HTTP Method Registry) is
safe and idempotent like GET but carries a request body like POST. It is wired
through exactly like PATCH:

- actix-web: `guard::Query()`, `web::query()`, `Resource::query()`, and
  `TestRequest::query()`
- actix-web-codegen: `#[query]` routing macro (plus re-export from actix-web)

`http` 0.2 has no `Method::QUERY` constant, so the method is built with
`Method::from_bytes(b"QUERY").unwrap()`, with a TODO to switch to the constant
once the `http` dependency is bumped (actix#3384). No dependency changes.
`actix-http` needs no change (it uses `http::Method` directly).

Tests mirror the existing PATCH coverage and add a body-carrying QUERY test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extend HTTP QUERY (RFC 10008) support to the remaining per-method
convenience surfaces, mirroring PATCH:

- awc: `Client::query()`
- actix-test: `TestServer::query()`
- actix-http-test: `TestServer::query()` and the HTTPS `TestServer::squery()`

Also tighten `TestRequest::query()`'s doc to match its sibling helpers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added A-awc project: awc A-web-codegen project: actix-web-codegen A-test project: actix-test A-web project: actix-web A-http-test project: actix-http-test labels Jul 8, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@Samielakkad Samielakkad left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core QUERY routing and awc::Client::query() paths have coverage, but the new test-server helpers look untested:

  • actix_test::TestServer::query()
  • actix_http_test::TestServer::query()
  • actix_http_test::TestServer::squery()

Those are small wrappers, but they are public convenience APIs and they can regress independently from web::query() / TestRequest::query() because they build full client requests from server URLs. It would be good to add a minimal test that starts a server with a web::query() route and reaches it through each new helper, at least for the non-TLS helpers if TLS coverage is awkward in this crate.

That would also prove the method survives the client/server round trip, not just the in-process service tests.

@github-actions github-actions Bot added the A-http project: actix-http label Jul 18, 2026
@mo-bruno

mo-bruno commented Jul 18, 2026

Copy link
Copy Markdown
Author

@Samielakkad added in fcbf37f, one per helper. test_query_method in actix-web's test_server.rs does the full round trip through a web::query() route, request body included. h1_query and h2_squery in the actix-http test files are the minimal version: the handler asserts the method comes through as QUERY and the client checks the response. TLS wasn't awkward after all since test_rustls.rs already uses sget(), and that path negotiates h2, so it also covers QUERY over HTTP/2, which nothing else did. Ready for another look.

Exercise each new helper against a live server:

- actix_test::TestServer::query() through a web::query() route,
  request body included
- actix_http_test::TestServer::query() over plaintext HTTP/1
- actix_http_test::TestServer::squery() over rustls, asserting the
  request arrives as QUERY over HTTP/2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mo-bruno
mo-bruno force-pushed the feat/query-method branch from 2a7a1b5 to fcbf37f Compare July 18, 2026 11:25
@mo-bruno
mo-bruno requested a review from Samielakkad July 18, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-awc project: awc A-http project: actix-http A-http-test project: actix-http-test A-test project: actix-test A-web project: actix-web A-web-codegen project: actix-web-codegen

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants