axum-patternslisted
Install: claude install-skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack
# Axum Patterns
## Full Application Structure
```toml
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
tower = "0.4"
tower-http = { version = "0.5", features = ["cors", "trace", "compression-gzip", "timeout"] }
serde = { version = "1", features = ["derive"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
```
```rust
use axum::{Router, routing::get};
use std::sync::Arc;
use tower::ServiceBuilder;
use tower_http::{cors::CorsLayer, trace::TraceLayer, timeout::TimeoutLayer};
#[derive(Clone)]
pub struct AppState {
pub db: Arc<DbPool>,
pub config: Arc<Config>,
}
pub fn create_router(state: AppState) -> Router {
Router::new()
.route("/health", get(health))
.nest("/api/v1/users", users::router())
.nest("/api/v1/auth", auth::router())
.layer(ServiceBuilder::new()
.layer(TraceLayer::new_for_http())
.layer(CorsLayer::permissive())
.layer(TimeoutLayer::new(std::time::Duration::from_secs(30))))
.fallback(not_found)
.with_state(state)
}
async fn health() -> &'static str { "ok" }
async fn not_found() -> (axum::http::StatusCode, &'static str) {
(axum::http::StatusCode::NOT_FOUND, "not found")
}
```
## Custom Extractors
```rust
use axum::{async_trait, extract::FromRequestParts, http::{request::Parts, StatusCode}};
// JWT auth extractor
pub struct AuthUser(pub Claims);
#[async_trait]
impl<S: Send + Sync> FromRequestParts<S> for AuthUser {