Skip to main content
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

Rejection
QueryRejection
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);

Form URL encoding

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"
}