Struct OriginalUri

pub struct OriginalUri(pub Uri);

Extractor that gets the original request URI regardless of nesting.

This is necessary since Uri, when used as an extractor, will have the prefix stripped if used in a nested service.

Example

use axum::{
    routing::get,
    Router,
    extract::OriginalUri,
    http::Uri
};

let api_routes = Router::new()
    .route(
        "/users",
        get(|uri: Uri, OriginalUri(original_uri): OriginalUri| async {
            // `uri` is `/users`
            // `original_uri` is `/api/users`
        }),
    );

let app = Router::new().nest("/api", api_routes);
# let _: Router = app;

Extracting via request extensions

OriginalUri can also be accessed from middleware via request extensions. This is useful for example with Trace to create a span that contains the full path, if your service might be nested:

use axum::{
    Router,
    extract::OriginalUri,
    http::Request,
    routing::get,
};
use tower_http::trace::TraceLayer;

let api_routes = Router::new()
    .route("/users/{id}", get(|| async { /* ... */ }))
    .layer(
        TraceLayer::new_for_http().make_span_with(|req: &Request<_>| {
            let path = if let Some(path) = req.extensions().get::<OriginalUri>() {
                // This will include `/api`
                path.0.path().to_owned()
            } else {
                // The `OriginalUri` extension will always be present if using
                // `Router` unless another extractor or middleware has removed it
                req.uri().path().to_owned()
            };
            tracing::info_span!("http-request", %path)
        }),
    );

let app = Router::new().nest("/api", api_routes);
# let _: Router = app;

Fields

0: Uri

Trait Implementations

impl Clone for OriginalUri

fn clone(&self) -> OriginalUri

impl Debug for OriginalUri

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

impl Deref for OriginalUri

type Target = Uri;
fn deref(&self) -> &Self::Target

impl DerefMut for OriginalUri

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

impl<S> FromRequestParts<S> for OriginalUri where S: Send + Sync,

type Rejection = never;
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection>

Auto Trait Implementations

impl !Freeze for OriginalUri

impl RefUnwindSafe for OriginalUri

impl Send for OriginalUri

impl Sync for OriginalUri

impl Unpin for OriginalUri

impl UnsafeUnpin for OriginalUri

impl UnwindSafe for OriginalUri

Blanket Implementations

impl<P, T> Receiver for OriginalUri where P: Deref<Target = T> + ?Sized, T: ?Sized,

type Target = T;

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

type Rejection = <T as FromRequestParts<S>>::Rejection;
fn from_request(req: Request<Body>, state: &S) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>>

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for OriginalUri where ST: ?Sized, DT: ?Sized,

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for OriginalUri where ST: ?Sized, DT: ?Sized,

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

fn type_id(&self) -> TypeId

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

fn borrow(&self) -> &T

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

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

impl<T> CloneToUninit for OriginalUri where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

impl<T> From<T> for OriginalUri

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> FromRef<T> for OriginalUri where T: Clone,

fn from_ref(input: &T) -> T

impl<T> Instrument for OriginalUri

impl<T> Read<Exclusive, BecauseExclusive> for OriginalUri where T: ?Sized,

impl<T> Same for OriginalUri

type Output = T;

impl<T> ToOwned for OriginalUri where T: Clone,

type Owned = T;
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)

impl<T> WithSubscriber for OriginalUri

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

fn into(self) -> U

Calls U::from(self).

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

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

type Error = never;
fn try_from(value: U) -> Result<T, never>

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

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

impl<V, T> VZip<V> for OriginalUri where V: MultiLane<T>,

fn vzip(self) -> V