Routing

Routing in warp is built by composing Filters 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));