Query parameters
Declares a typed view of the request's query string.
Apply #[query_params] to a struct with named fields. The macro derives serde::Deserialize, so each field maps to a key in the query string.
#[query_params]
struct PageQuery {
page: Option<u32>,
}
Reading the value
Read the struct with query_params::<T>(cx). It returns Result<&T, &QueryParamsError> and caches the result for the request. A QueryParamsError identifies the field that failed to parse. The struct is independent of the route, so any handler can read it.
Failing with an error response
Set error = ... to convert parse failures into a router error. Callers can then propagate the error with ?:
// src/app/posts.rs
#[query_params(error = bad_request)]
struct PageQuery {
page: Option<u32>,
}
#[page]
async fn posts(cx: &Cx) -> Result<impl View> {
// Responds with a 400 naming the failing key when the query string
// does not match.
let query = query_params::<PageQuery>(cx)?;
Ok(view! { "currently on page: " (query.page) })
}
The forms mirror the router's error constructors:
error = not_foundresponds 404 withNotFoundError.error = unauthorizedresponds 401 withUnauthorizedError.error = forbiddenresponds 403 withForbiddenError.error = bad_requestresponds 400 withBadRequestError. The description names the failing key, likeinvalid query value: invalid digit found in string (at `page`); pass your own witherror = bad_request("invalid search").error = redirect("/search")anderror = redirect_permanent("/search")send the client to the given URI withRedirectError.
Without error = ..., the same conversions are available per call site through RouterErrorExt, which also suits handlers that want different responses for the same struct.
Clearing the query string with redirect("?")
The client resolves a redirect target against the current URL. The target "?" reloads the current page with an empty query string:
#[query_params(error = redirect("?"))]
struct PageQuery {
page: Option<u32>,
}
Use this only when an empty query string is valid. Otherwise the redirected request fails again and creates a redirect loop.
Requirements
- Use
Option<T>for optional keys. A missing key and an empty value (?page=, as a browser sends for a blank input) both read asNone.#[serde(default)]is not applied, so a missing key on a non-Optionfield is a parse error. - The struct must be
Send + Sync + 'static, since it is memoized for the request.