Extractor that deserializes query strings into some type.
The type parameter T must implement serde::Deserialize.
Type signature
pub struct Query<T>(pub T);
Usage
Basic example
use axum::{
extract::Query,
routing::get,
Router,
};
use serde::Deserialize;
#[derive(Deserialize)]
struct Pagination {
page: usize,
per_page: usize,
}
// This will parse query strings like `?page=2&per_page=30` into `Pagination`
// structs.
async fn list_things(Query(pagination): Query<Pagination>) {
let page = pagination.page;
let per_page = pagination.per_page;
// ...
}
let app = Router::new().route("/list_things", get(list_things));
Optional query parameters
Use Option fields in your struct to make query parameters optional:
use serde::Deserialize;
#[derive(Deserialize)]
struct Params {
page: Option<usize>,
per_page: Option<usize>,
}
async fn handler(Query(params): Query<Params>) {
let page = params.page.unwrap_or(1);
let per_page = params.per_page.unwrap_or(10);
// ...
}
Default values
Combine with #[serde(default)] for default values:
use serde::Deserialize;
#[derive(Deserialize)]
struct Params {
#[serde(default = "default_page")]
page: usize,
#[serde(default = "default_per_page")]
per_page: usize,
}
fn default_page() -> usize { 1 }
fn default_per_page() -> usize { 10 }
Multiple values
Query parameters with the same name can be collected into a Vec:
use serde::Deserialize;
#[derive(Deserialize)]
struct Filters {
tags: Vec<String>,
}
// Query string: ?tags=rust&tags=web&tags=axum
async fn handler(Query(filters): Query<Filters>) {
// filters.tags = ["rust", "web", "axum"]
}
Error handling
Returned when the query string cannot be parsed into the target type.
If the query string cannot be deserialized, the request will be rejected with a 400 Bad Request response.
// Query string: ?page=invalid
// Results in: "Failed to deserialize query string: page: invalid digit found in string"
Parsing from URI
You can also parse query parameters directly from a Uri:
use axum::extract::Query;
use http::Uri;
use serde::Deserialize;
#[derive(Deserialize)]
struct ExampleParams {
foo: String,
bar: u32,
}
let uri: Uri = "http://example.com/path?foo=hello&bar=42".parse().unwrap();
let result: Query<ExampleParams> = Query::try_from_uri(&uri).unwrap();
assert_eq!(result.foo, String::from("hello"));
assert_eq!(result.bar, 42);
Query strings use the same encoding as application/x-www-form-urlencoded form data. Special characters are percent-encoded:
// Query string: ?search=hello%20world
#[derive(Deserialize)]
struct Search {
search: String,
}
async fn handler(Query(search): Query<Search>) {
// search.search = "hello world"
}