Project Structuring

1. Welcome and Icebreaker:

Have you ever worked on a project that became hard to manage? What would you do differently next time?

2. Outline the Session:

Agenda:

  1. Concept Explanation: How to organize a growing Axum project.
  2. Live Coding: Refactor an app into modules (handlers, models, etc.).
  3. Tasks: Practice by modularizing your own project.

Learning Outcomes:

  • Organize Axum projects into logical modules.
  • Refactor code for maintainability and clarity.

Expectations: Try splitting your code into modules and see how it improves readability!

3. Concept Explanation:

As your Axum app grows, organizing code into modules (e.g., handlers, models, db, middleware) helps keep things maintainable. Each module should have a clear responsibility. Use mod and pub to control visibility.

4. Live Coding Demonstration:

// src/main.rs
mod handlers;
mod models;
mod db;
mod errors;

use axum::Router;
use handlers::hello::hello;

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", axum::routing::get(hello));
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

// src/handlers/mod.rs
pub mod hello;

// src/handlers/hello.rs
pub async fn hello() -> &'static str {
    "Hello from handlers!"
}

// src/models/mod.rs
// (Your data models go here)

// src/db/mod.rs
// (Your database logic goes here)

// src/errors/mod.rs
// (Your error types go here)

Best Practices:

  • Group related code together in folders (e.g., handlers/, models/, db/, errors/).
  • Use mod.rs as the entry point for each module folder.
  • Keep files focused and avoid large, monolithic modules.

Common Pitfalls:

  • Making everything pub unnecessarily.
  • Letting modules or folders become too large or unfocused.

4.1. Example Project Folder Structure (Diagram):

Here’s a typical folder-based structure for a medium-sized Axum project:

my-axum-app/
├── src/
│   ├── main.rs           # Application entry point
│   ├── handlers/
│   │   ├── mod.rs        # Handlers module root
│   │   └── hello.rs      # Example handler
│   ├── models/
│   │   └── mod.rs        # Data models
│   ├── db/
│   │   └── mod.rs        # Database logic
│   ├── errors/
│   │   └── mod.rs        # Custom error types
│   ├── middleware/
│   │   └── mod.rs        # Custom middleware
│   └── ...               # Other modules as needed
├── Cargo.toml            # Rust project manifest
└── README.md             # Project documentation
  • Each folder represents a logical module and can be expanded as your project grows.
  • Use submodules (files inside folders) for further organization.

5. Tasks

  • Create a db module for database logic.
  • Move error types into an errors module.
  • Refactor your app to use the new structure and test all endpoints.