HTTP methods
One attribute per HTTP method, taking the route path as its only argument:
#[get], #[post], #[put], #[delete], #[patch], #[head], #[options], #[trace],
#[connect].
use axumstart::router::get;
#[get("/users/me")]
async fn current_user() -> &'static str {
"me"
}
This submits a route registration via inventory — serve (or
axumstart_router::register_routes directly) folds every registered route onto the Router
at startup. There's no manual .route("/users/me", get(current_user)) call to write or forget.
Exactly one method attribute per handler
A handler needs exactly one of these attributes. Zero is just a plain function (not registered as a route); more than one is a compile error:
#[get("/a")]
#[post("/a")] // error: only one HTTP method attribute is allowed per handler
async fn conflicting() -> &'static str { "no" }
If you need the same logic reachable from two methods, write two small handlers that both call
a shared function, or route both to one handler manually via a hand-built Router merged in
elsewhere (see serve for how auto-registered and manual routes combine).
Extractors work normally
The router state is always Components, so any extractor that
works against it — Inject<T>, State<Components>, or any
ordinary Axum extractor (Json<T>, Query<T>, path params, etc.) — works exactly as it would in
a hand-built Router:
use axum::extract::Path;
use axumstart::components::component;
use axumstart::router::{Inject, get};
struct Greeting(&'static str);
#[component] // registered the same way as any other component — see the components docs
fn build_greeting() -> Greeting {
Greeting("hello")
}
#[get("/greet/{name}")]
async fn greet(Path(name): Path<String>, Inject(greeting): Inject<Greeting>) -> String {
format!("{}, {name}", greeting.0)
}
Combining with #[layer(...)]
See #[layer(...)] for attaching per-route middleware — it stacks with any of the
method attributes above, in either order.