Path patterns
A path pattern is a string that determines which requests are matched by a given route based on their path.
Static paths
The simplest case is a static path, a path pattern that matches a single, fixed path:
use pavex::Response;
use pavex::get;
#[get(path = "/greet")]
pub fn anonymous_greet() -> Response {
Response::ok().set_typed_body("Hello world!")
}
It will only match requests with a path that is exactly equal to /greet.
Path parameters
Static paths are fairly limited. The real power of path patterns comes from their ability to match dynamic paths:
use pavex::Response;
use pavex::get;
use pavex::request::path::PathParams;
#[PathParams]
pub struct Info {
pub name: String,
}
#[get(path = "/greet/{name}")]
pub fn informal_greet(info: PathParams<Info>) -> Response {
let body = format!("Hello, {}!", info.0.name);
Response::ok().set_typed_body(body)
}
The {name} segment is a path parameter.
It matches everything after /greet/, up to the next / or the end of the path.
It matches, for example, /greet/Ursula and /greet/John. It won't match /greet/ though!
You can have multiple path parameters in a single path pattern, as long as they are don't belong to the same segment:
use pavex::Response;
use pavex::get;
use pavex::request::path::PathParams;
#[PathParams]
pub struct Info {
pub first_name: String,
pub last_name: String,
}
#[get(path = "/greet/{first_name}/{last_name}")]
pub fn formal_greet(info: PathParams<Info>) -> Response {
let body = format!("Hello, {} {}!", info.0.first_name, info.0.last_name);
Response::ok().set_typed_body(body)
}
Catch-all parameters
Normal path parameters match a single path segment—they stop at the next / or at the end of the path.
You can use the * character to craft a catch-all path parameter. It matches the rest of the path, regardless of its contents:
use pavex::Response;
use pavex::get;
use pavex::request::path::PathParams;
#[PathParams]
pub struct Info {
pub name: String,
pub details: Vec<String>,
}
#[get(path = "/info/{name}/{*details}")]
pub fn detailed_info(info: PathParams<Info>) -> Response {
let body = format!("Hello, {}!", info.0.name);
Response::ok().set_typed_body(body)
}
{*details} matches everything after /info/{name}, even if it contains / characters.
/info/{name}/{*details} matches, for example, /info/ursula/le_guin and /info/ursula/mc_guire, but it also matches /info/ursula/mc_guire/le_guin.
It won't match /info/ursula/mc_guire/le_guin/ though! The matched portion can't be empty.
To avoid ambiguity, you can have at most one catch-all parameter per path pattern and it must be at the end of the path pattern.
Accessing path parameters
Path parameters are not discarded after a request has been routed. You can access their values from your handler or from middlewares.
Check out the "Path parameters" guide for more details.