Supergloo is a Rust library designed to simplify route creation in Axum web applications. It automatically generates routes based on your handler functions' module paths and names, reducing boilerplate code.
- Automatic Route Generation: Define your handlers in modules, and Supergloo automatically maps them to URL paths.
- Convention-Based Routing: Follows a simple convention:
crate::routes::path::to::handler_fn
becomes/path/to/handler_fn/
. - Macro-Based: Uses the
#[gloo_handler]
attribute macro to mark functions as route handlers. - Simple Integration: Easily merge generated routes into your main Axum router.
Add supergloo
and its companion macro crate gloo_macros
to your Cargo.toml
:
[dependencies]
axum = "0.7" # Or your desired version
tokio = { version = "1", features = ["full"] } # Needed for the Axum runtime
supergloo = { path = "../supergloo" } # Or use git/crates.io version
gloo_macros = { path = "../macros" } # Or use git/crates.io version
Create your Axum handler functions within modules, typically under a src/routes/
directory. Mark each handler function with the #[gloo_handler]
attribute. The attribute can optionally take the HTTP method as a string (e.g., "post", "put"). If omitted, it defaults to "get".
// src/routes/mod.rs
use axum::response::{IntoResponse, Response};
use gloo_macros::gloo_handler;
// This creates the route: GET /
#[gloo_handler]
async fn base() -> Response {
"Welcome home!".into_response()
}
// This creates the route: GET /dashboard/
#[gloo_handler("get")]
async fn dashboard() -> Response {
"User Dashboard".into_response()
}
pub mod api {
// src/routes/api/mod.rs
use axum::response::{IntoResponse, Response};
use gloo_macros::gloo_handler;
#[gloo_handler]
async fn base() -> Response {
"API Base".into_response()
}
pub mod users {
// src/routes/api/users.rs
use axum::response::{IntoResponse, Response};
use gloo_macros::gloo_handler;
#[gloo_handler]
async fn base() -> Response {
"List users".into_response()
}
#[gloo_handler("post")]
async fn create() -> Response {
"Create user".into_response()
}
}
}
Supergloo uses the module_path!()
macro to determine the base path.
- Removes the leading parts of the path up to and including the first
routes
segment. For example,my_crate::routes::api::users
becomesapi::users
. - Segments are joined by
/
. - If the function name is
base
, it maps to the module's path (e.g.,routes::api::base
->/api/
). - If the function name is not
base
, the function name is appended (e.g.,routes::api::users::create
->/api/users/create/
). - Paths are normalized to start and end with
/
.
In your main.rs
or wherever you set up your Axum application, import the necessary items and use the .gloo_routes()
method on your axum::Router
. Make sure to import your routes module to ensure the handlers are discovered.
// src/main.rs
use axum::Router;
use supergloo::routing::GlooRouting;
mod routes;
#[tokio::main]
async fn main() {
let app = Router::new()
.gloo_routes();
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
println!("Listening on http://127.0.0.1:3000");
axum::serve(listener, app).await.unwrap();
}
Compile and run your application:
cargo run
Then access the routes:
- http://127.0.0.1:3000/
- http://127.0.0.1:3000/dashboard/
- http://127.0.0.1:3000/api/
- http://127.0.0.1:3000/api/users/
- http://127.0.0.1:3000/api/users/create/
Supergloo uses the inventory
crate behind the scenes.
- The
#[gloo_handler]
macro wraps your function and registers aGlooHandler
struct (containing the module path, function name, and a function pointer to create the AxumMethodRouter
) withinventory::submit!
. .gloo_routes()
iterates through all registeredGlooHandler
instances usinginventory::iter
.- For each handler, it processes the
module_path
andfn_name
to construct the final URL path according to the conventions described. - Creates the specific
axum::routing::MethodRouter
(e.g.,get(handler_fn)
) and adds it to a new router. - Merges this router containing all discovered routes into the router you called
.gloo_routes()
on.
This project is licensed under the MIT License or Apache License 2.0.