Dynami
A Rust library for automatic Axum router generation from directory structure. Generate type-safe routers for Axum 0.8+ by organizing your route handlers into a folder hierarchy.
Features
- File-system based routing - Routes are automatically generated from your folder structure
- Soft overwriting - Preserves your custom code outside of generated sections
- Smart route detection - Won't overwrite routes you've manually defined
- Dynamic routes - Use
d_prefix for path parameters (e.g.,d_id->/{id}) - Wildcard routes - Support for multi-segment captures (e.g.,
d_*rest->/{*rest}) - State detection - Automatically detects and applies your AppState type
- All HTTP methods - GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD
- Auto-generated handlers - Creates default handlers for empty method files
Installation
Add to your Cargo.toml:
[]
= "0.1"
[]
= "0.1"
Usage
1. Create a folder structure for your routes
src/routes/
├── mod.rs # Root router (optional AppState here)
├── get.rs # GET /
├── post.rs # POST /
└── api/
├── mod.rs # API router
├── get.rs # GET /api
└── d_id/
├── mod.rs # Dynamic router
└── get.rs # GET /api/{id}
2. Create a build.rs file
use format_routes;
3. Run your build
The library will generate:
router()functions in eachmod.rspub moddeclarations for subdirectories- Default handlers for empty method files
- Proper type annotations with your AppState
4. Use the generated router in your application
async
How it Works
Generated Code with dynami::generate!
The library uses the dynami::generate! macro to mark generated code blocks:
use Router;
use get;
Key benefits:
- Add custom routes before or after the generated block
- The generator detects your manual routes and won't duplicate them
- Smart import generation: only imports the HTTP methods actually used (e.g.,
use axum::routing::{get, post}only if both are used) - If you remove
dynami::generate!, the file won't be updated anymore - The macro is a simple pass-through that returns its input, so the code compiles normally
HTTP Method Files
Create files named after HTTP methods:
get.rs-> GET handlerpost.rs-> POST handlerput.rs-> PUT handlerdelete.rs-> DELETE handlerpatch.rs-> PATCH handleroptions.rs-> OPTIONS handlerhead.rs-> HEAD handler
Dynamic Routes
Use the d_ prefix for path parameters:
d_id/->/{id}routed_user_id/->/{user_id}routed_*rest/->/{*rest}wildcard route (captures remaining path)
AppState Detection
Add your state struct to the root mod.rs:
The library will:
- Detect the
AppStatestruct (or any struct with "State" in its name) - Generate
Router<AppState>for all routers - Include
Stateextractors in default handlers
Examples
Simple API
routes/
├── mod.rs
├── get.rs # GET / - list all
└── post.rs # POST / - create new
Generates:
use Router;
use ;
Nested Routes
routes/
├── mod.rs
├── get.rs
└── api/
├── mod.rs
├── get.rs
└── users/
├── mod.rs
└── get.rs
Generates in routes/mod.rs:
use Router;
use get;
Mixing Manual and Generated Routes
// routes/mod.rs
use Router;
use get;
// Custom handler defined locally
async
With AppState
// routes/mod.rs
use PgPool;
// routes/get.rs
use State;
use IntoResponse;
use AppState;
pub async
Default Handlers
Empty method files get default handlers:
// Without state
use IntoResponse;
pub async
// With state (when AppState is detected)
use State;
use IntoResponse;
pub async
Best Practices
- Run in build.rs - Generate routes during build time
- Keep the
dynami::generate!block - If you remove it, the file won't be updated - Add custom code outside the generate block - Your code won't be overwritten
- Use meaningful folder names - They become route paths
- Implement handlers - Replace default "OK" responses with real logic
- Define custom routes before the generate block - They'll be detected and not duplicated
Limitations
- Axum doesn't support regex in path parameters (use middleware for validation)
- Route generation happens at build time (requires rebuild for new routes)
- Wildcard routes must use
d_*prefix (e.g.,d_*rest)
License
This project is open source and available under the MIT License.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.