Expand description
§Web Route
web-route provides an ergonomic way to define and manage web server routes in Rust.
Most web frameworks define routes using &str templates (e.g. "/foo/{param}"). This approach can become error-prone when you need to:
- Generate a callable version of a route (with parameters populated), for use in internal redirects, integration tests, etc.
- Join routes across nested routers — without having to worry about whether strings have leading/trailing slashes or resorting to
format!()gymnastics.
§Features
- Cleanly define and join route segments
- Generate template routes for framework registration
- Generate populated routes with runtime parameters
- Slash handling is automatic and consistent
§Usage
One can create and join WebRoutes without having to worry about leading and trailing slash pedantics. The resulting routes will always be normalized to have single forward slash separators no matter the operating system.
use web_route::WebRoute;
let foo = WebRoute::new("no/leading/slash/");
let bar = WebRoute::new("/leading/and//trailing/slash/");
// Can join `WebRoute`s.
let joined_route = foo.join(bar);
assert_eq!(&joined_route.to_string(), "/no/leading/slash/leading/and/trailing/slash");
// Can join `String`s and `&str`.
let joined_route = foo.join("/a/str/route");
assert_eq!(&joined_route.to_string(), "/no/leading/slash/a/str/route");WebRoutes can be serialized and deserialized.
use serde::{Serialize, Deserialize};
use web_route::WebRoute;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct FooStruct {
route: WebRoute
}
let foo_struct = FooStruct {
route: WebRoute::new("/foo/bar/baz"),
};
let serialized = serde_json::to_string(&foo_struct).unwrap();
let deserialized = serde_json::from_str::<FooStruct>(&serialized).unwrap();
assert_eq!(deserialized, foo_struct);One would use a ParameterizedRoute when defining routes used by a webserver (e.g. axum)
use web_route::ParameterizedRoute;
let foo = ParameterizedRoute::new("/foo/{foo_id}");
let bar = ParameterizedRoute::new("/bar/{bar_id}");
assert_eq!(&foo.join(bar).to_string(), "/foo/{foo_id}/bar/{bar_id}");A ParameterizedRoute can be populated with values to produce a WebRoute which can then be used to make a request to the server route it defines.
use serde::{Serialize, Deserialize};
use web_route::ParameterizedRoute;
let foo = ParameterizedRoute::new("/foo/{foo_id}");
let bar = ParameterizedRoute::new("/bar/{bar_id}");
#[derive(Serialize, Deserialize)]
struct Params {
foo_id: String,
bar_id: String,
}
let params = Params {
foo_id: "value_foo".to_owned(),
bar_id: "value_bar".to_owned(),
};
let web_route = foo.join(bar).to_web_route(¶ms).unwrap();
assert_eq!(&web_route.to_string(), "/foo/value_foo/bar/value_bar");For more complete examples, see the examples and integration tests.
§Potential Improvements
- Enable compile-time validation of routes and parameters for even greater safety.
§Prior Art
TypedPath: Theaxum-extracrate provides theTypedPathtrait with a#[derive(TypedPath)]implementation. It enables type-safe, compile-time-checked population of path parameters and returns aUrisuitable for use in requests. However, it does not appear to offer a clean or ergonomic way to compose or join multiple routes.
§Feature Flags
fake: Implementsfake::DummyonWebRouteandParameterizedRoute.
Re-exports§
pub use parameterized_route::route::ParameterizedRoute;pub use web_route::route::WebRoute;