Browse documentation
Documentation

Query parameters

Edit this guide on GitHub

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:

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