Skip to content

Support the HTTP QUERY verb (RFC 10008) in Wolverine.HTTP#3296

Merged
jeremydmiller merged 1 commit into
mainfrom
feat/http-query-verb
Jul 5, 2026
Merged

Support the HTTP QUERY verb (RFC 10008) in Wolverine.HTTP#3296
jeremydmiller merged 1 commit into
mainfrom
feat/http-query-verb

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Adds [WolverineQuery("/route")] for the HTTP QUERY method (RFC 10008, June 2026).

What QUERY is

QUERY is a safe, idempotent method — like GET — that additionally carries a request body. It's the "GET with a body" for search/query endpoints whose criteria are too large or structured for the query string.

What changed

Wolverine.HTTP's endpoint machinery is almost entirely verb-agnostic, so QUERY needed just one new attribute plus one OpenAPI fix:

  • Attribute: WolverineQueryAttribute : WolverineHttpMethodAttribute (base("QUERY", template)), discovered generically like every other verb. Uses the literal "QUERY" so it works on net9.0 and net10.0 alike (the net10-only HttpMethods.Query isn't required).
  • Routing (no change needed): the verb flows to ASP.NET Core as HttpMethodMetadata; there's no verb allow-list, so "QUERY" matches.
  • Request body (no change needed): body binding is skipped only for "GET" (JsonHandling.cs), so QUERY binds a body exactly like POST.
  • Transactions (no change needed): exemption is dependency-based (HttpChain.RequiresOutbox() → outbox only when the handler depends on IMessageBus/MessageContext). A safe QUERY endpoint is therefore never wrapped in transactional/outbox middleware — even under AutoApplyTransactions() — with no verb special-casing.
  • OpenAPI (the one real fix): OpenAPI 3.1 (what the Swashbuckle / Microsoft.OpenApi stack emits) has no QUERY operation — Swashbuckle throws a KeyNotFoundException mapping the method, which would break document generation for the whole app. WolverineApiDescriptionProvider now gracefully omits QUERY endpoints from the API description, matching ASP.NET Core's own OpenAPI 3.1 behavior. Endpoints stay fully routable; first-class OpenAPI 3.2 documentation can follow once the stack supports it.

Tests (query_verb_support.cs)

  • Reads a request body and returns the result (driven via a real QUERY request through the test server's HttpClient, since Alba's scenario helpers assume standard verbs).
  • Route carries the correct HttpMethodMetadata ("QUERY").
  • Not wrapped in transactional middleware (RequiresOutbox() false) even with AutoApplyTransactions() on.
  • swagger.json generation still succeeds with a QUERY endpoint present (QUERY gracefully omitted).

Research notes

  • ASP.NET Core (.NET 10) exposes HttpMethods.Query/IsQuery and registers QUERY via MapMethods, but deliberately cut MapQuery and [HttpQuery] in API review — so a [WolverineQuery] attribute is the natural Wolverine equivalent.
  • QUERY becomes a first-class operation in OpenAPI 3.2; .NET 11 preview emits it (via x-oai-additionalOperations for 3.1). This PR targets parity with .NET 10 (graceful omission on 3.1).

Docs: new "The HTTP QUERY Method" section in guide/http/endpoints.md (usage + the transaction and OpenAPI notes). Follow-up AI-skill coverage tracked separately.

🤖 Generated with Claude Code

Adds [WolverineQuery("/route")] for the QUERY method — a safe, idempotent verb (like
GET) that additionally carries a request body, for search/query endpoints whose criteria
are too large or structured for the query string.

Almost all of Wolverine.Http's endpoint machinery is verb-agnostic, so QUERY works with a
single new attribute:
  * Routing: the verb flows to ASP.NET Core as HttpMethodMetadata string(s); no allow-list.
  * Request body: body binding is only skipped for "GET", so QUERY binds a body like POST.
  * Transactions: exemption is dependency-based (outbox only when the handler depends on
    IMessageBus/MessageContext), so a safe QUERY endpoint is never transactional — even
    under AutoApplyTransactions — without any verb special-casing.

The one place that needed handling is OpenAPI: OpenAPI 3.1 (the Swashbuckle /
Microsoft.OpenApi stack Wolverine emits with) has no QUERY operation and Swashbuckle
throws mapping the method, which would break document generation for the whole app.
WolverineApiDescriptionProvider now gracefully omits QUERY endpoints from the API
description — matching ASP.NET Core's own OpenAPI 3.1 behavior. The endpoints stay fully
routable; first-class OpenAPI 3.2 documentation can follow once the stack supports it.

Tests: QUERY endpoint reads a request body, carries correct HttpMethodMetadata, is not
wrapped in transactional middleware, and does not break swagger generation. Docs added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jeremydmiller
jeremydmiller merged commit 2806714 into main Jul 5, 2026
26 checks passed
This was referenced Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant