Skip to content

Path prefixes

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

src/intro/blueprint.rs
use pavex::blueprint::router::GET;
use pavex::blueprint::Blueprint;
use pavex::f;

pub fn bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.prefix("/homes").nest({
        /* (1)! */
        let mut bp = Blueprint::new();
        bp.route(GET, "/", f!(super::list_homes));
        bp.route(GET, "/{id}", f!(super::get_home));
        bp
    });
    bp.route(GET, "/", f!(super::index));
    bp
}
  1. Here we are using a block expression since the nested blueprint is particularly short. If it's more complex, you can build it in a separate function, as shown in the next section.

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:

  • /homes/ and /homes/{id}, after applying the /homes 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.

src/deep/blueprint.rs
use pavex::blueprint::router::GET;
use pavex::blueprint::Blueprint;
use pavex::f;

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

pub fn homes_bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.route(GET, "/", f!(super::list_homes));
    bp.prefix("/{home_id}").nest(home_bp());
    bp
}

pub fn home_bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.route(GET, "/", f!(super::get_home));
    bp.prefix("/rooms").nest(rooms_bp());
    bp
}

pub fn rooms_bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.route(GET, "/", f!(super::list_rooms));
    bp.route(GET, "/{room_id}", f!(super::get_room));
    bp
}

The get_room request handler will be available at /homes/{home_id}/rooms/{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:

src/consecutive/blueprint.rs
use pavex::blueprint::router::GET;
use pavex::blueprint::Blueprint;
use pavex::f;

pub fn bp() -> Blueprint {
    let mut bp = Blueprint::new();
    bp.prefix("/prefix").nest({
        let mut bp = Blueprint::new();
        bp.route(GET, "//path", f!(super::handler));
        bp
    });
    bp
}