# Organizing Your Project
As your Actix Web application grows beyond a single file, it's essential to organize your code to maintain readability and maintainability. While Rust allows you to structure projects however you want, certain patterns are common in web applications.
##A Scalable Layout
A standard REST API might be organized like this:
src/
├── main.rs # Entry point, HttpServer setup
├── db.rs # Database connection and models
├── handlers/ # Request handlers (controllers)
│ ├── mod.rs # Handler exports
│ ├── users.rs # User-related endpoints
│ └── posts.rs # Post-related endpoints
├── middleware/ # Custom middleware
├── models/ # Data structures and Serde models
└── routes.rs # Route definitions grouping#The `routes.rs` Module
Instead of cluttering main.rs with every single route registration, you can use Actix Web's ServiceConfig to group routes into modules.
// src/handlers/users.rs
use actix_web::{get, HttpResponse, Responder};
#[get("/")]
pub async fn get_all_users() -> impl Responder {
HttpResponse::Ok().body("List of users")
}
// src/routes.rs
use actix_web::web;
use crate::handlers::users;
pub fn configure(cfg: &mut web::ServiceConfig) {
cfg.service(
web::scope("/users")
.service(users::get_all_users)
);
}Then, in main.rs:
use actix_web::{App, HttpServer};
mod handlers;
mod routes;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().configure(routes::configure)
})
.bind("127.0.0.1:8080")?
.run()
.await
}##Modularity
This ServiceConfig pattern allows you to cleanly separate concerns. A large application might have multiple config functions across different modules, each responsible for configuring its own routes and state.
By keeping your routes, models, and handlers distinct, you ensure that your code remains testable and easy to navigate for new developers joining your project.