Loading...
Loading...
Configure Salvo routers with path parameters, nested routes, and filters. Use for complex routing structures and RESTful APIs.
npx skill4agent add salvo-rs/salvo-skills salvo-routinghoop()push()Router::with_path("users").get(list_users){id}<id>// Basic parameter
Router::with_path("users/{id}").get(show_user)
// Typed parameter (num, i32, i64, etc.)
Router::with_path("users/{id:num}").get(show_user)
// Regex pattern
Router::with_path(r"users/{id|\d+}").get(show_user)
// Wildcard (captures rest of path)
Router::with_path("files/{**path}").get(serve_file)#[handler]
async fn show_user(req: &mut Request) -> String {
let id = req.param::<i64>("id").unwrap();
format!("User ID: {}", id)
}{}<>{*}Router::new().path("{*}").get(catch_all){**}Router::new().path("static/{**path}").get(serve_static)
// Matches: static/css/style.css, static/js/main.js, etc.Router::new().path("files/{*rest}").get(handler)
// In handler: req.param::<String>("rest")let router = Router::new()
.push(
Router::with_path("api/v1")
.push(
Router::with_path("users")
.get(list_users)
.post(create_user)
.push(
Router::with_path("{id}")
.get(show_user)
.patch(update_user)
.delete(delete_user)
)
)
.push(
Router::with_path("posts")
.get(list_posts)
.post(create_post)
)
);fn user_routes() -> Router {
Router::with_path("users")
.get(list_users)
.post(create_user)
.push(
Router::with_path("{id}")
.get(get_user)
.patch(update_user)
.delete(delete_user)
)
}
fn post_routes() -> Router {
Router::with_path("posts")
.get(list_posts)
.post(create_post)
}
let api_v1 = Router::with_path("v1")
.push(user_routes())
.push(post_routes());
let api_v2 = Router::with_path("v2")
.push(user_routes())
.push(post_routes());
let router = Router::new()
.push(Router::with_path("api/v1/users").get(list_users).post(create_user))
.push(Router::with_path("api/v1/users/{id}").get(show_user).patch(update_user).delete(delete_user));Router::new()
.get(handler) // GET
.post(handler) // POST
.put(handler) // PUT
.patch(handler) // PATCH
.delete(handler) // DELETE
.head(handler) // HEAD
.options(handler); // OPTIONSuse salvo::routing::filters;
// Path filter
Router::with_filter(filters::path("users"))
// Method filter
Router::with_filter(filters::get())
// Combined filters
Router::with_filter(filters::path("users").and(filters::get()))hoop()let router = Router::new()
.hoop(logging) // Applies to all routes
.path("api")
.push(
Router::new()
.hoop(auth_check) // Only applies to routes under this
.path("users")
.get(list_users)
.post(create_user)
);use salvo::prelude::*;
use salvo::writing::Redirect;
// Permanent redirect (301)
#[handler]
async fn permanent_redirect(res: &mut Response) {
res.render(Redirect::permanent("/new-location"));
}
// Temporary redirect (302)
#[handler]
async fn temporary_redirect(res: &mut Response) {
res.render(Redirect::found("/temporary-location"));
}
// See Other (303)
#[handler]
async fn see_other(res: &mut Response) {
res.render(Redirect::see_other("/another-page"));
}use salvo::prelude::*;
use salvo::routing::filter::Filter;
use uuid::Uuid;
pub struct GuidFilter;
impl Filter for GuidFilter {
fn filter(&self, req: &mut Request, _state: &mut PathState) -> bool {
if let Some(param) = req.param::<String>("id") {
Uuid::parse_str(¶m).is_ok()
} else {
false
}
}
}
#[handler]
async fn get_user_by_guid(req: &mut Request) -> String {
let id = req.param::<Uuid>("id").unwrap();
format!("User GUID: {}", id)
}
let router = Router::new()
.path("users/{id}")
.filter(GuidFilter)
.get(get_user_by_guid);{id:/\d+/}{id}