Chapter 9e — Searching with the HTTP QUERY method (RFC 10008)
3 tests, no DB — one product-search handler serving both GET and
QUERY from the same code. Run with
cargo test --test cookbook_chapter09e_query_search.
QUERY is the "safe GET with a body": safe + idempotent like GET, but
the search criteria travel in the request body — so a search too big or
too structured for a querystring (long filter lists, arrays, nested
criteria) doesn't have to masquerade as a POST. Two pieces combine:
QueryRouterExt::query routes QUERY alongside GET on one path, and
the Params<T> extractor reads T from the querystring on GET and
from the body on QUERY.
use rustango::params::Params;
use rustango::http_query::QueryRouterExt;
use axum::routing::get;
async fn search(Params(q): Params<ProductQuery>) -> Json<Value> { /* filter */ }
Router::new().route("/products", get(search).query(search));
- §9.119 —
GET /products?q=cable&max_price=15and the same criteria in a urlencodedQUERYbody return identical results. →get_and_query_urlencoded_agree - §9.119 — a
QUERYJSON body carries a real array ({"tags":["usb","hdmi"]}) — awkward in a querystring, natural in a body. →query_json_body_matches_multiple_tags - §9.119 — an empty
QUERYbody returns the whole catalog. →empty_query_returns_everything
See the QUERY method guide for the
full framework surface (routing, CSRF/CORS, caching, ViewSet query
action, OpenAPI 3.2).