Crate axum_folder_router

Source
Expand description

§axum_folder_router Macro Documentation

folder_router! is a procedural macro for the Axum web framework that automatically generates router boilerplate based on your file structure. It simplifies route organization by using filesystem conventions to define your API routes.

§Installation

Add the dependency to your Cargo.toml:

[dependencies]
axum_folder_router = "0.1.0"
axum = "0.8"

§Basic Usage

The macro scans a directory for route.rs files and automatically creates an Axum router based on the file structure:

use axum::Router;
use axum_folder_router::folder_router;

#[derive(Clone, Debug)]
struct AppState {
    _foo: String,
}

folder_router!("./examples/simple/api", AppState);

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Create app state
    let app_state = AppState {
        _foo: "".to_string(),
    };

    // Generate the router using the macro
    let folder_router: Router<AppState> = folder_router();

    // Build the router and provide the state
    let app: Router<()> = folder_router.with_state(app_state);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
    println!("Listening on http://{}", listener.local_addr()?);
    axum::serve(listener, app).await?;
    Ok(())
}

§File Structure Convention

The macro converts your file structure into routes:

src/api/
├── route.rs                 -> "/"
├── hello/
│   └── route.rs             -> "/hello"
├── users/
│   ├── route.rs             -> "/users"
│   └── [id]/
│       └── route.rs         -> "/users/{id}"
└── files/
    └── [...path]/
        └── route.rs         -> "/files/*path"

Each route.rs file can contain HTTP method handlers that are automatically mapped to the corresponding route.

§Route Handlers

Inside each route.rs file, define async functions named after HTTP methods:

use axum::response::{Html, IntoResponse};

pub async fn get() -> impl IntoResponse {
    Html("<h1>Hello World!</h1>").into_response()
}

pub async fn post() -> impl IntoResponse {
    "Posted successfully".into_response()
}

§Supported Features

§HTTP Methods

The macro supports all standard HTTP methods:

  • get
  • post
  • put
  • delete
  • patch
  • head
  • options

§Path Parameters

Dynamic path segments are defined using brackets:

src/api/users/[id]/route.rs   -> "/users/{id}"

Inside the route handler:

use axum::{
  extract::Path,
  response::IntoResponse
};

pub async fn get(Path(id): Path<String>) -> impl IntoResponse {
    format!("User ID: {}", id)
}

§Catch-all Parameters

Use the spread syntax for catch-all segments:

src/api/files/[...path]/route.rs   -> "/files/*path"
use axum::{
  extract::Path,
  response::IntoResponse
};

pub async fn get(Path(path): Path<String>) -> impl IntoResponse {
    format!("Requested file path: {}", path)
}

§State Extraction

The state type provided to the macro is available in all route handlers: All routes share the same state type, though you can use FromRef for more granular state extraction.

use axum::{
  extract::State,
  response::IntoResponse
};


pub async fn get(State(state): State<AppState>) -> impl IntoResponse {
    format!("State: {:?}", state)
}

§Limitations

  • Compile-time Only: The routing is determined at compile time, so dynamic route registration isn’t supported.

Macros§

folder_router
Creates an Axum router module tree & creation function by scanning a directory for route.rs files.