# Axum Template Usage Guide This repository is a **cargo-generate** template for creating new Axum web services with a pre-configured, production-ready setup. ## Quick Start ### Prerequisites Install `cargo-generate`: ```bash cargo install cargo-generate ``` ### Generate a New Project #### From a Git Repository (Recommended for Production Use) ```bash cargo generate --git https://gitea.fasharp.io/fa-sharp/axum-template ``` #### From Local Path (For Testing) ```bash cargo generate --path /path/to/axum-template ``` ### Interactive Prompts When you run `cargo generate`, you'll be prompted for: 1. **Project name**: The name of your new project (e.g., `my-api-server`) 2. **Project description**: Brief description (e.g., "REST API for user management") 3. **Environment variable prefix**: Prefix for configuration env vars (e.g., `APP` → `APP_HOST`, `APP_PORT`) 4. **Default port**: Server's default port (e.g., `8080`) 5. **Default log level**: Choose from `trace`, `debug`, `info`, `warn`, or `error` 6. **Include aide**: Whether to include OpenAPI documentation support (`true` or `false`) ### Non-Interactive Mode You can skip prompts by providing values via CLI: ```bash cargo generate --git \ --name my-service \ --define project-description="My awesome service" \ --define env_prefix="API" \ --define default_port="3000" \ --define default_log_level="info" \ --define include_aide=true ``` ## Generated Project Structure ``` my-project/ ├── src/ │ ├── main.rs # Application entry point with server setup │ ├── lib.rs # App initialization and plugin registration │ ├── config.rs # Configuration management (figment-based) │ └── state.rs # Application state management ├── Cargo.toml # Dependencies (customized based on your choices) ├── .env.example # Example environment variables ├── .gitignore # Pre-configured for Rust projects └── README.md # Project-specific README ``` ## Configuration The generated project uses environment variables for configuration. The prefix is customizable during generation. Example with `APP` prefix: ```bash # Required APP_API_KEY=your-secret-api-key # Optional (defaults are set during template generation) APP_HOST=127.0.0.1 APP_PORT=8080 APP_LOG_LEVEL=info ``` In development, copy `.env.example` to `.env`: ```bash cp .env.example .env # Edit .env with your values ``` ## Features Included ### Core Features (Always Included) - **Axum 0.8** - Modern, ergonomic web framework - **Environment-based Config** - `figment` for flexible configuration - **Structured Logging** - `tracing` with JSON output in production - **Graceful Shutdown** - Handles SIGTERM, SIGINT, and Ctrl-C - **Plugin Architecture** - `axum-app-wrapper` for modular initialization - **Rust 2024 Edition** - Latest language features ### Optional Features - **OpenAPI Documentation** - `aide` and `schemars` (optional during generation) ## Next Steps After Generation 1. **Navigate to your project**: ```bash cd my-project ``` 2. **Configure environment**: ```bash cp .env.example .env # Edit .env with your actual values ``` 3. **Run in development**: ```bash cargo run ``` 4. **Add your routes**: - Create a new module for your routes - Implement a plugin function - Register it in `src/lib.rs` 5. **Build for production**: ```bash cargo build --release ``` ## Customization Tips ### Adding Routes Create a new module (e.g., `src/routes.rs`): ```rust use axum::{routing::get, Router}; use axum_app_wrapper::AdHocPlugin; use crate::state::AppState; pub fn plugin() -> AdHocPlugin { AdHocPlugin::new().on_router(|router| async move { let routes = Router::new() .route("/health", get(health_check)); Ok(router.merge(routes)) }) } async fn health_check() -> &'static str { "OK" } ``` Register it in `src/lib.rs`: ```rust pub async fn create_app() -> anyhow::Result<(axum::Router, AppConfig, impl Future + Send)> { let (router, state, on_shutdown) = App::new() .register(config::plugin()) .register(routes::plugin()) // Add this line .init() .await?; let app_config = state.config.to_owned(); Ok((router.with_state(state), app_config, on_shutdown)) } ``` ### Adding Dependencies Just edit `Cargo.toml` as normal: ```bash cargo add sqlx --features postgres,runtime-tokio ``` ### Changing the Environment Prefix The prefix is baked in during template generation. To change it later, search and replace in: - `src/config.rs` (the `extract_config` function) - `.env.example` ## Publishing Your Template ### GitHub 1. Push this directory to GitHub 2. Enable "Template repository" in Settings 3. Others can use: `cargo generate --git https://github.com/you/axum-template` ### GitLab/Gitea 1. Push to your instance 2. Share the URL: `cargo generate --git https://gitea.example.com/you/axum-template` ### Private Repositories cargo-generate supports authentication: ```bash cargo generate --git https://github.com/you/private-template --branch main # You'll be prompted for credentials if needed ``` ## Template Maintenance ### Updating Dependencies Update the versions in `Cargo.toml.liquid` and commit: ```bash # Edit Cargo.toml.liquid git add Cargo.toml.liquid git commit -m "Update dependencies" git push ``` ### Testing the Template Generate a test project locally: ```bash cargo generate --path . --name test-project --define include_aide=true cd test-project cargo check cargo test ``` ## Troubleshooting ### "Failed to parse Cargo.toml" - Make sure template syntax is on separate lines in `.liquid` files - Cargo-generate needs `.liquid` extension for files with Jinja2 syntax ### Missing Imports in Generated Code - Check that Rust edition is set to 2024 in `Cargo.toml.liquid` - Edition 2024 includes `Future` in the prelude ### Conditional Features Not Working - Use `{% if variable %}...{% endif %}` syntax - Keep conditionals on their own lines in TOML files - Test with both `true` and `false` values ## License Configure the license for your template as appropriate. The generated projects will inherit this license unless modified.