axum::extract

Struct Path

Source
pub struct Path<T>(pub T);
Expand description

Extractor that will get captures from the URL and parse them using serde.

Any percent encoded parameters will be automatically decoded. The decoded parameters must be valid UTF-8, otherwise Path will fail and return a 400 Bad Request response.

§Example

These examples assume the serde feature of the uuid crate is enabled.

One Path can extract multiple captures. It is not necessary (and does not work) to give a handler more than one Path argument.

use axum::{
    extract::Path,
    routing::get,
    Router,
};
use uuid::Uuid;

async fn users_teams_show(
    Path((user_id, team_id)): Path<(Uuid, Uuid)>,
) {
    // ...
}

let app = Router::new().route("/users/:user_id/team/:team_id", get(users_teams_show));

If the path contains only one parameter, then you can omit the tuple.

use axum::{
    extract::Path,
    routing::get,
    Router,
};
use uuid::Uuid;

async fn user_info(Path(user_id): Path<Uuid>) {
    // ...
}

let app = Router::new().route("/users/:user_id", get(user_info));

Path segments also can be deserialized into any type that implements serde::Deserialize. This includes tuples and structs:

use axum::{
    extract::Path,
    routing::get,
    Router,
};
use serde::Deserialize;
use uuid::Uuid;

// Path segment labels will be matched with struct field names
#[derive(Deserialize)]
struct Params {
    user_id: Uuid,
    team_id: Uuid,
}

async fn users_teams_show(
    Path(Params { user_id, team_id }): Path<Params>,
) {
    // ...
}

// When using tuples the path segments will be matched by their position in the route
async fn users_teams_create(
    Path((user_id, team_id)): Path<(String, String)>,
) {
    // ...
}

let app = Router::new().route(
    "/users/:user_id/team/:team_id",
    get(users_teams_show).post(users_teams_create),
);

If you wish to capture all path parameters you can use HashMap or Vec:

use axum::{
    extract::Path,
    routing::get,
    Router,
};
use std::collections::HashMap;

async fn params_map(
    Path(params): Path<HashMap<String, String>>,
) {
    // ...
}

async fn params_vec(
    Path(params): Path<Vec<(String, String)>>,
) {
    // ...
}

let app = Router::new()
    .route("/users/:user_id/team/:team_id", get(params_map).post(params_vec));

§Providing detailed rejection output

If the URI cannot be deserialized into the target type the request will be rejected and an error response will be returned. See customize-path-rejection for an example of how to customize that error.

Tuple Fields§

§0: T

Trait Implementations§

Source§

impl<T: Debug> Debug for Path<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Deref for Path<T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<T> DerefMut for Path<T>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<T, S> FromRequestParts<S> for Path<T>
where T: DeserializeOwned + Send, S: Send + Sync,

Source§

type Rejection = PathRejection

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
Source§

fn from_request_parts<'life0, 'life1, 'async_trait>( parts: &'life0 mut Parts, _state: &'life1 S, ) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Perform the extraction.

Auto Trait Implementations§

§

impl<T> Freeze for Path<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Path<T>
where T: RefUnwindSafe,

§

impl<T> Send for Path<T>
where T: Send,

§

impl<T> Sync for Path<T>
where T: Sync,

§

impl<T> Unpin for Path<T>
where T: Unpin,

§

impl<T> UnwindSafe for Path<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S, T> FromRequest<S, ViaParts> for T
where S: Send + Sync, T: FromRequestParts<S>,

Source§

type Rejection = <T as FromRequestParts<S>>::Rejection

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
Source§

fn from_request<'life0, 'async_trait>( req: Request<Body>, state: &'life0 S, ) -> Pin<Box<dyn Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>> + Send + 'async_trait>>
where 'life0: 'async_trait, T: 'async_trait,

Perform the extraction.
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.

Layout§

Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.