Skip to content

Path prefixes

You can use Blueprint::prefix to group multiple routes under a common path prefix.

use pavex::{Blueprint, blueprint::from, get, http::StatusCode};

pub fn bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.prefix("/home").routes(from![self::home]);
    bp.route(INDEX);
    // [...]
}

#[get(path = "/")]
pub fn index() -> StatusCode {
    // [...]
}

pub mod home {
    use super::*;

    #[get(path = "/")]
    pub fn list_homes() -> StatusCode {
        // [...]
    }

    #[get(path = "/{home_id}")]
    pub fn get_home() -> StatusCode {
        // [...]
    }
}

The prefix is prepended to the path of all routes nested under it. In the example above, we end up with three different route paths:

  • /home/ and /home/{id}, after applying the /home prefix
  • /, not influenced by the prefix

Prefixes are concatenated

You aren't limited to a single level of nesting. You can break down your routes into as many levels as you need—path prefixes will be concatenated in the order they were declared.

use pavex::{Blueprint, get, http::StatusCode};

pub fn bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.prefix("/home").nest(home_bp());
    // [...]
}

pub fn home_bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.prefix("/{home_id}").nest(room_bp());
    // [...]
}

pub fn room_bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.route(GET_ROOM);
    // [...]
}

#[get(path = "/room/{room_id}")]
pub fn get_room() -> StatusCode {
    StatusCode::OK
}

The get_room route will be available at /home/{home_id}/room/{room_id}, after prepending all relevant prefixes.

Path parameters are allowed

As shown in the previous example, your path prefixes can contain path parameters.
There is no difference between a path parameter in a prefix and a path parameter in a route path.

Restrictions

There are a few restrictions to keep in mind when using path prefixes:

  • Prefixes can't be empty.
  • Prefixes must start with a / character.
  • Prefixes must not end with a / character.

These constraints are enforced by Pavex at compile-time.

Trailing slashes

Pavex forbids trailing / in path prefixes as a safety measure.
It's easy to accidentally end up with consecutive / if a prefix ends with a /—e.g. /prefix//path, using /prefix/ as prefix and /path for your route.

Since consecutive slashes are rarely desirable, you must add them explicitly to your route path if that's what you want:

use pavex::{Blueprint, get, http::StatusCode};

pub fn bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.prefix("/prefix").nest({
        let mut bp = Blueprint::new();
        bp.route(HANDLER);
        bp
    });
    bp
}

#[get(path = "//path")]
pub fn handler() -> StatusCode {
    // [...]
}