Introduction to Laravel’s MVC architecture — A Complete Beginner’s Guide with Examples and Workflows

Introduction to Laravel’s MVC architecture — A Complete Beginner’s Guide with Examples and Workflows

Known for its elegant syntax and developer-friendly structure, Laravel is one of the most powerful PHP frameworks out there.

Laravel’s core architecture is Model-View-Controller (MVC), a design pattern that breaks an application into three interacting and separated components to avoid an unorganized code base.

This article takes a closer look at the MVC architecture of Laravel and breaks this architecture down into concrete examples and workflows, and it will walk you through each component with practical code snippets and best practices.

Basic understanding of MVC in Laravel

Model-View-Controller (MVC) programming concept invented to organize specifically our server-side applications. So understanding this structure is fundamental for developers looking to build reliable and efficient applications with Laravel.


What is the design pattern ?

A design pattern, such as MVC, is a proven concept adopted to provide solutions to a common problem in software design, which is to provide a structured approach to writing maintainable and scalable applications. It helps simplify complex problems, promote best practices, and facilitate collaboration.


What Is MVC?

MVC is a design pattern that divides an application into three interrelated components: Model, View, and Controller.

Entity separation ensures that each component is isolated and has its own responsibilities, promotes scalability by allowing applications to grow by adding or removing some features without affecting other existing code, and enables teams to collaborate efficiently by working separately on models, views, and controllers simultaneously.

  • Model (M): Represents the data and business logic of the application. It manages database interactions, relationships, queries, and domain rules.
  • View (V): Handles the presentation layer, rendering the user interface using Laravel’s Blade templating engine.
  • Controller (C): Acts as a mediator, processing user requests, applying application logic, and orchestrating interactions between models and views.


The Model: The Business Logic

The role of the model in MVC is to encapsulate core business processes, reduce redundancy by centralizing domain rules, and provide a strong foundation for scalable applications.

Model typically ships with Eloquent ORM to provide an expressive syntax for interacting with databases, supports mass mapping to create models using arrays instead of manually setting properties, establishes relationships between tables such as hasMany and belongsTo, and events to hook into model lifecycle events such as created, updated, or deleted.

The Model handles:

  • Database operations (queries, inserts, updates, deletes).
  • Data relationships (e.g., one-to-many, many-to-many).
  • Scopes, accessors, and mutators for efficient data manipulation.
  • Business rules (e.g., “Banking system, allow loans on positive accounts”).

Business Logic Example:

In an Ecommerce app, the business logic might handle the calculation of a discount based on the user’s membership status or the total value of their shopping cart.

For instance:

  • If a user is a premium member, a 15% discount is applied automatically to their total cart value.
  • If the total cart value exceeds a certain threshold (e.g., $75), an additional discount (e.g., 8.5%) is applied.


Controller: The request manager (Usually handles technical and application logic)

The Controller is responsible for:

  • Receiving HTTP requests and directing them appropriately.
  • Applying application logic (e.g., validation, authentication, authorization, permissions).
  • Coordinating communication between models and views.
  • Handling various response types like JSON, views, or redirects.

Application Logic Example:

Whenever a customer hits the “confirm purchase” button , the controller performs several tasks. First, it validates the items in the shopping cart to make sure they are still in stock. It then verifies that the customer is eligible for a transaction, and confirms that the transaction is successful or returns an error if the payment fails. Finally, the controller sends a response to the user interface, confirming the order and displaying a success or error message, depending on the outcome.


The View: The Rendering Interface

Presenting data to the user in a readable, accessible format is the responsibility of the view. To create dynamic content, Laravel uses Blade, a powerful templating engine.

The role of the view in MVC is to render application data, responses in a visual and interactive format, not to contain business or application logic.

Laravel views include blade templates for adding logic such as loops and conditionals while maintaining readability, component-based views for creating reusable UI elements to reduce duplication, and layouts and sections for maintaining a consistent structure across pages.


Bigger Model, Smaller Controller

Laravel’s (and MVC’s) philosophy of “bigger models, smaller controllers” means that more business logic and application rules are placed inside a model (or dedicated service class) instead of being accumulated into a controller. The goal is to keep controllers lean, focusing only on handling HTTP requests, validating inputs, handling exceptions, and returning responses.

But for more complex logic, use the service layer to avoid bloated models.


Business Logic vs Application Logic

Business Logic

Business logic defines the core rules and operations that reflect a company’s real-world processes and are aligned with business goals. It focuses on “what” rather than “how”, and is independent of the technical implementation.

Example:

Imagine an ecommerce application where a 7% discount is applied when the order total exceeds $100:

// In App\Models\Order.php
public function calcDiscount(){
  if ($this->totalAmount >= 100) {
    return $this->totalAmount * 0.07; // 7% discount
  }
  return 0;
}

Application Logic

The application logic handles the technical execution of orders within the application:

  • Handles request routing, database interactions, and UI presentation.
  • Ensures the application follows technical requirements like form validation, etc.

Example:

// In App\Http\Controllers\OrderController.php

public function store(Request $request){

  $validated = $request->validate([
    'customer_id' => 'required|exists:customers,id',
    'totalAmount' => 'required|numeric|min:0',
  ]);

  $order = Order::create($validated);

  return response()->json([
    'status' => 'success',
    'message' => 'Order created successfully.'
  ],201);

}


Step 1. Setting Up a Laravel Project

To get started with Laravel, ensure you have PHP, Composer, and Laravel installed. Then, create a new project using:

composer create-project laravel/laravel mvc-project

Navigate to the project directory:

cd mvc-project

PS. The installation of new versions of Laravel is already shipped with the sqlite connection for quick project setup.

Now let’s break down the MVC architecture using a simple order management example.


Step 2. Creating the Order model

Eloquent ORM is used in Laravel to make models interact with the database. Let’s create an Order model with a migration at the same time with -m flag at the end:

php artisan make:model Order -m

This command generates:

app/Models/Order.php

database/migrations/2025_02_16_153349_create_orders_table.php

Modify the migration file:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration{

  /**
  * Run the migrations.
  */
  public function up(): void{
    Schema::create('orders', function (Blueprint $table) {
      $table->id();
      $table->decimal('totalAmount', 20, 2);
      $table->timestamps();
    });
  }
  
  /**
  * Reverse the migrations.
  */
  public function down(): void{
    Schema::dropIfExists('orders');
  }

};

Run the migration:

php artisan migrate

Define the model attributes in app/Models/Order.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Order extends Model{
  protected $fillable = ['totalAmount'];
}

Step 3. Create a controller to manage application requests

Controllers are responsible for the processing of user requests and the way in which data is processed.

Create a OrderController:

-r, to instruct Laravel to add automatically the controller hooks;

php artisan make:controller OrderController -r

Modify app/Http/Controllers/OrderController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Order;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    public function index()
    {
        $orders = Order::all();
        return view('orders.index', compact('orders'));
    }

    public function create()
    {
        return view('orders.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'totalAmount' => 'required|numeric|min:0',
        ]);

        Order::create(['totalAmount' => $validated['totalAmount']]);

        return redirect()->route('orders.index')->with('success', 'Order created successfully.');
    }

    public function show(Order $order)
    {
        return view('orders.show', compact('order'));
    }

    public function edit(Order $order)
    {
        return view('orders.edit', compact('order'));
    }

    public function update(Request $request, Order $order)
    {
        $validated = $request->validate([
            'totalAmount' => 'required|numeric|min:0'
        ]);

        $order->update(['totalAmount' => $validated['totalAmount']]);

        return redirect()->route('orders.index')->with('success', 'Order updated successfully.');
    }

    public function destroy(Order $order)
    {
        $order->delete();

        return redirect()->route('orders.index')->with('success', 'Order deleted successfully.');
    }
}

Step 4. Render the View using Blade

Using Blade templates, views are responsible for presenting data. Within resources/views, create an orders folder and add the following files

resources/views/orders/index.blade.php

Or run the execute the command below:

php artisan make:view orders/index<h1>Orders List</h1>
<a href="{{ route('orders.create') }}">Create New Order</a>
@foreach ($orders as $order)
  <div>
    <h2>{{ $order->totalAmount }}</h2>
    <a href="{{ route('orders.show', $order) }}">View</a>
    <a href="{{ route('orders.edit', $order) }}">Edit</a>
    <form method="POST" action="{{ route('orders.destroy', $order) }}">
      @csrf
      @method('DELETE')
      <button type="submit">Delete</button>
    </form>
  </div>
@endforeach

Step 5. Defining Routes

Modify routes/web.php to define the routes for the orders:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\OrderController;

// We follow the name conventions like index, show, etc, so we can use implicitly Route::resource;
Route::resource('orders', OrderController::class);


Step.6 Running the Application

Start the server:

php artisan serve

Visit http://127.0.0.1:8000/orders in your browser to see orders.

P.S If you get 404 page, try to remove routes cache by running:

php artisan route:clear


Summary

  1. User sends requests: The user visits /orders, and Laravel routes the request to OrderController@index().
  2. Controller Fetches Data: The index() method retrieves orders records from the database.
  3. View Renders Data: The index.blade.php file displays the orders list.
  4. User Interacts and keeps sending requests to the controller: Creating, updating, or deleting orders triggers corresponding controller actions.
  5. Database Updates: The model (Order) interacts with the database to store or modify data.
  6. Response is Sent: Return a response message with redirect.


The MVC architecture of Laravel offers an effective method of structuring applications through the separation of different aspects. The model handles data and business logic, the view presents visual representations of data, and the controller handles http requests.

By following this structured approach, you can build scalable and maintainable applications effortlessly. If you are new to Laravel, experimenting with this example will solidify your understanding of MVC, preparing you for more advanced features like Events, Broadcasting, etc.