> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/tokio-rs/axum/llms.txt
> Use this file to discover all available pages before exploring further.

# Query

> Deserialize query strings into Rust types

Extractor that deserializes query strings into some type.

The type parameter `T` must implement `serde::Deserialize`.

## Type signature

```rust theme={null}
pub struct Query<T>(pub T);
```

## Usage

### Basic example

```rust theme={null}
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:

```rust theme={null}
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:

```rust theme={null}
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`:

```rust theme={null}
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

<ParamField path="Rejection" type="QueryRejection">
  Returned when the query string cannot be parsed into the target type.
</ParamField>

If the query string cannot be deserialized, the request will be rejected with a `400 Bad Request` response.

```rust theme={null}
// 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`:

```rust theme={null}
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:

```rust theme={null}
// Query string: ?search=hello%20world
#[derive(Deserialize)]
struct Search {
    search: String,
}

async fn handler(Query(search): Query<Search>) {
    // search.search = "hello world"
}
```
