Routing
Routing in warp
is built by composing Filter
s that match different parts of the request path. The primary tools for this are warp::path()
and the path!
macro.
Static Path Segments
To match a specific, non-changing part of a path, use a string literal with warp::path()
.
use warp::Filter;
// Matches requests to /hello
let hello = warp::path("hello");
The path!
Macro
For routes with multiple segments, the path!
macro provides a more ergonomic and readable syntax. It combines static segments and parameters seamlessly.
use warp::Filter;
// Matches requests to /hello/from/warp
let route = warp::path!("hello" / "from" / "warp");
Path Parameters
To capture a dynamic segment of the path, you can specify a type in the path!
macro or use warp::path::param()
. Any type that implements std::str::FromStr
can be used as a parameter.
use warp::Filter;
// Matches GET /sum/:u32/:u32
// For example: /sum/5/10
let sum = warp::path!("sum" / u32 / u32)
.map(|a, b| format!("{} + {} = {}", a, b, a + b));
// Matches GET /:u16/times/:u16
// For example: /3/times/7
let times = warp::path!(u16 / "times" / u16)
.map(|a, b| format!("{} * {} = {}", a, b, a * b));
If the path segment cannot be parsed into the specified type, the filter will reject the request, typically resulting in a 404 Not Found
response.
Matching the End of the Path
It's often important to ensure you're matching the entire path, not just a prefix. For example, you want a filter for /users
to match /users
but not /users/123
.
The warp::path::end()
filter matches the end of the request path. The path!
macro automatically adds this for you.
use warp::Filter;
// This will match `/math` and `/math/`, but not `/math/sum`
let math_root = warp::path("math").and(warp::path::end());
// The path! macro does this automatically:
// This matches `/math` but not `/math/anything`
let also_math_root = warp::path!("math");
Creating Path Prefixes
If you want to create a filter that matches a prefix of a path without matching the end, you can use the / ..
syntax within the path!
macro. This is useful for grouping related routes under a common base path.
use warp::Filter;
// Create a filter for the '/api/v1' prefix.
let api_prefix = warp::path!("api" / "v1" / ..);
let users = warp::path("users").map(|| "List of users");
let products = warp::path("products").map(|| "List of products");
// Combine the prefix with other routes.
// This will match `/api/v1/users` and `/api/v1/products`.
let api = api_prefix.and(users.or(products));