# MVC Architecture in Hostbasket This document explains the Model-View-Controller (MVC) architecture used in the Hostbasket application. ## Table of Contents 1. [Introduction to MVC](#introduction-to-mvc) 2. [MVC Components in Hostbasket](#mvc-components-in-hostbasket) 3. [Data Flow in MVC](#data-flow-in-mvc) 4. [Benefits of MVC](#benefits-of-mvc) 5. [Best Practices](#best-practices) 6. [Examples](#examples) ## Introduction to MVC Model-View-Controller (MVC) is a software architectural pattern that separates an application into three main logical components: - **Model**: Represents the data and business logic of the application - **View**: Represents the user interface - **Controller**: Acts as an intermediary between Model and View This separation helps in organizing code, making it more maintainable, testable, and scalable. ## MVC Components in Hostbasket ### Model In Hostbasket, models are defined in the `src/models` directory. They represent the data structures and business logic of the application. ```rust // src/models/user.rs pub struct User { pub id: Option, pub name: String, pub email: String, pub password_hash: Option, pub role: UserRole, pub created_at: Option>, pub updated_at: Option>, } ``` Models are responsible for: - Defining data structures - Implementing business logic - Validating data - Interacting with the database (in a full implementation) ### View Views in Hostbasket are implemented using Tera templates, located in the `src/views` directory. They are responsible for rendering the user interface. ```html {% extends "base.html" %} {% block title %}Home - Hostbasket{% endblock %} {% block content %}

Welcome to Hostbasket!

A web application framework built with Actix Web and Rust.

{% endblock %} ``` Views are responsible for: - Presenting data to the user - Capturing user input - Providing a user interface - Implementing client-side logic (with JavaScript) ### Controller Controllers in Hostbasket are defined in the `src/controllers` directory. They handle HTTP requests, process user input, interact with models, and render views. ```rust // src/controllers/home.rs pub struct HomeController; impl HomeController { pub async fn index(tmpl: web::Data, session: Session) -> Result { let mut ctx = tera::Context::new(); ctx.insert("active_page", "home"); // Add user to context if available if let Ok(Some(user)) = session.get::("user") { ctx.insert("user_json", &user); } render_template(&tmpl, "home/index.html", &ctx) } } ``` Controllers are responsible for: - Handling HTTP requests - Processing user input - Interacting with models - Preparing data for views - Rendering views ## Data Flow in MVC The typical data flow in an MVC application like Hostbasket is as follows: 1. The user interacts with the view (e.g., submits a form) 2. The controller receives the request 3. The controller processes the request, often interacting with models 4. The controller prepares data for the view 5. The controller renders the view with the prepared data 6. The view is displayed to the user This flow ensures a clear separation of concerns and makes the application easier to maintain and extend. ## Benefits of MVC Using the MVC architecture in Hostbasket provides several benefits: 1. **Separation of Concerns**: Each component has a specific responsibility, making the code more organized and maintainable. 2. **Code Reusability**: Models and controllers can be reused across different views. 3. **Parallel Development**: Different team members can work on models, views, and controllers simultaneously. 4. **Testability**: Components can be tested in isolation, making unit testing easier. 5. **Flexibility**: Changes to one component have minimal impact on others. 6. **Scalability**: The application can grow without becoming unwieldy. ## Best Practices When working with the MVC architecture in Hostbasket, follow these best practices: ### Models - Keep models focused on data and business logic - Implement validation in models - Use traits to define common behavior - Keep database interactions separate from business logic ### Views - Keep views simple and focused on presentation - Use template inheritance to avoid duplication - Minimize logic in templates - Use partials for reusable components ### Controllers - Keep controllers thin - Focus on request handling and coordination - Delegate business logic to models - Use dependency injection for services ## Examples ### Complete MVC Example Here's a complete example of how the MVC pattern works in Hostbasket for a user registration flow: #### Model (src/models/user.rs) ```rust impl User { pub fn new_with_password(name: String, email: String, password: &str) -> Result { let password_hash = hash(password, DEFAULT_COST)?; Ok(Self { id: None, name, email, password_hash: Some(password_hash), role: UserRole::User, created_at: Some(Utc::now()), updated_at: Some(Utc::now()), }) } pub fn verify_password(&self, password: &str) -> Result { match &self.password_hash { Some(hash) => verify(password, hash), None => Ok(false), } } } ``` #### View (src/views/auth/register.html) ```html {% extends "base.html" %} {% block title %}Register - Hostbasket{% endblock %} {% block content %}

Register

{% endblock %} ``` #### Controller (src/controllers/auth.rs) ```rust pub async fn register( form: web::Form, session: Session, _tmpl: web::Data ) -> Result { // Create a new user with the form data let user = match User::new_with_password( form.name.clone(), form.email.clone(), &form.password ) { Ok(user) => user, Err(_) => return Err(actix_web::error::ErrorInternalServerError("Failed to create user")), }; // In a real application, you would save the user to a database here // Generate JWT token let token = Self::generate_token(&user.email, &user.role) .map_err(|_| actix_web::error::ErrorInternalServerError("Failed to generate token"))?; // Store user data in session let user_json = serde_json::to_string(&user).unwrap(); session.insert("user", &user_json)?; session.insert("auth_token", &token)?; // Create a cookie with the JWT token let cookie = Cookie::build("auth_token", token) .path("/") .http_only(true) .secure(false) // Set to true in production with HTTPS .max_age(actix_web::cookie::time::Duration::hours(24)) .finish(); // Redirect to the home page with JWT token in cookie Ok(HttpResponse::Found() .cookie(cookie) .append_header((header::LOCATION, "/")) .finish()) } ``` This example demonstrates how the MVC pattern separates concerns while allowing the components to work together to handle user registration.