When you install a fresh Laravel project, one of the very first directories you encounter is the app/ folder. This directory contains the heart of your application—its core logic, the main structure of its MVC components, and the essential classes that make your Laravel project function as a modern, organized, and maintainable web application.
In Laravel’s architecture, the app/ folder acts as the engine room of your application. It contains controllers, models, middleware, jobs, events, listeners, service providers, policies, and more. All the classes inside app/ are automatically loaded via Composer’s PSR-4 autoloading.
This article provides a deep, detailed, roughly 3000-word explanation of the app/ directory, its subfolders, and the role each plays in the structure of a Laravel application. Code examples are included to clarify typical usage.
Understanding the Structure of the app/ Folder
A fresh Laravel installation includes several subdirectories inside the app/ folder. Depending on your Laravel version and the features you enable, some of these may appear or not. But at a minimum, you will always see folders like:
app/
Console/
Exceptions/
Http/
Models/
Providers/
You may also see:
app/
Events/
Jobs/
Listeners/
Mail/
Notifications/
Policies/
Rules/
This guide explains each of these folders in depth, but the user specifically pointed out:
- Http/Controllers
- Http/Middleware
- Models
Since these are central to Laravel’s MVC architecture, we will cover them extensively while also explaining the broader context.
MVC and the Role of the app/ Folder
Laravel follows the Model–View–Controller pattern. The MVC pattern organizes your application into three major parts:
- Models: Represent data and interact with the database.
- Views: Render HTML output.
- Controllers: Handle user requests and return responses.
Within the Laravel structure, the “Models” and “Controllers” pieces of MVC reside directly under the app/ folder.
The app/Http/ Directory
The Http/ folder is one of the most important in the entire Laravel framework. It contains the entry pipelines through which all HTTP requests travel.
app/
Http/
Controllers/
Middleware/
Kernel.php
The Http/ folder contains:
- Controllers
- Middleware
- Form Requests (in
Requests/) - The HTTP Kernel
- Route Middleware Groups
We will break these down into clear sections.
What’s Inside app/Http/Controllers/
The Controllers/ directory contains your application’s controllers. Controllers are responsible for handling incoming requests. They are the main point of interaction between routes and application logic.
A typical controller looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
return 'List of users';
}
public function show($id)
{
return 'Showing user with ID: ' . $id;
}
}
The Purpose of Controllers
Controllers allow you to organize request-handling logic into structured, reusable classes. Instead of writing everything inside your routes/web.php or routes/api.php files, you delegate work to controller methods.
A route that uses this controller might look like:
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
Resource Controllers
Laravel includes a convenient “resource controller” option that automatically creates CRUD methods:
php artisan make:controller PostController --resource
This generates:
index()
create()
store()
show()
edit()
update()
destroy()
Typical resource controller snippet:
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|max:255',
'body' => 'required'
]);
$post = Post::create($validated);
return redirect()->route('posts.index');
}
Single-Action Controllers
Laravel also supports single-action (invokable) controllers:
php artisan make:controller ShowProfile --invokable
Example:
public function __invoke($id)
{
return 'Profile: ' . $id;
}
Routes:
Route::get('/profile/{id}', ShowProfile::class);
What’s Inside app/Http/Middleware/
Middleware acts as filters for incoming HTTP requests. They sit in the request pipeline to inspect or modify requests before they reach controllers.
Common examples:
- Checking authentication
- Logging requests
- Restricting access by IP
- Trimming whitespace
- Verifying CSRF tokens
A typical middleware looks like:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckAdmin
{
public function handle($request, Closure $next)
{
if (! $request->user() || ! $request->user()->is_admin) {
abort(403, 'Unauthorized');
}
return $next($request);
}
}
To register middleware, use:
app/Http/Kernel.php
Example registration:
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\CheckAdmin::class,
];
Then you can use it in a route:
Route::get('/admin', function () {
return 'Admin panel';
})->middleware('admin');
Middleware Groups
Laravel includes middleware groups like:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Routes using the API middleware automatically have throttling and JSON formatting behaviors.
The app/Models/ Directory
In older Laravel versions, models lived directly inside the app/ folder. Since Laravel 8, they now live in:
app/Models/
A model represents a database table. It interacts with the database through Eloquent ORM.
Sample model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = ['title', 'body'];
}
Defining Relationships
Eloquent makes it simple to define relationships:
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
Querying Using Models
$posts = Post::all();
$post = Post::find(1);
$recent = Post::where('created_at', '>=', now()->subDays(7))->get();
Creating Records
Post::create([
'title' => 'My First Post',
'body' => 'Content here...'
]);
Updating Records
$post = Post::find(1);
$post->update([
'title' => 'Updated Title'
]);
Deleting Records
Post::destroy(1);
Models are the backbone of Laravel’s database layer, forming the “M” in MVC.
Other Important Directories Inside app/
Although the user-focused request mentioned Controllers, Middleware, and Models, it is useful to understand the other folders within app/. These also play vital roles.
app/Console/
Contains custom Artisan commands and the kernel that defines scheduled tasks.
Example command:
php artisan make:command SendNewsletter
Example class:
public function handle()
{
$this->info('Sending newsletter...');
}
Scheduled tasks appear in:
app/Console/Kernel.php
Example:
protected function schedule(Schedule $schedule)
{
$schedule->command('newsletter:send')->daily();
}
app/Exceptions/
This folder manages the exception handling logic.
app/Exceptions/Handler.php
Example customization:
public function render($request, Throwable $e)
{
return response()->json([
'error' => $e->getMessage()
], 500);
}
You can also define custom exception classes here.
app/Providers/
Service providers are central to Laravel’s bootstrapping process.
Example provider:
php artisan make:provider CustomServiceProvider
Inside:
public function register()
{
// Bind services into the service container
}
public function boot()
{
// Boot logic executed after registration
}
Service providers are located in:
config/app.php
app/Events/ and app/Listeners/
Laravel supports an event-driven architecture.
Example event:
php artisan make:event UserRegistered
Example listener:
php artisan make:listener SendWelcomeEmail
Events trigger actions:
event(new UserRegistered($user));
Listeners respond to events.
app/Jobs/
Jobs represent tasks that can be processed synchronously or queued.
Example job:
php artisan make:job ProcessOrder
public function handle()
{
// Perform task
}
Jobs integrate with Laravel’s queue system.
app/Mail/
Used to send emails.
Example:
php artisan make:mail WelcomeEmail
Mail class:
public function build()
{
return $this->subject('Welcome')
->view('emails.welcome');
}
app/Notifications/
Laravel’s notification system supports email, SMS, Slack, and database notifications.
Example:
php artisan make:notification InvoicePaid
app/Policies/
Policies authorize user actions.
Example:
php artisan make:policy PostPolicy --model=Post
app/Rules/
Custom validation rules go here.
Example:
php artisan make:rule Uppercase
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
Why the app/ Folder Is the Backbone of Laravel
The app/ directory is the center of the application’s architecture for several reasons:
- It houses the MVC components that define your business logic.
- It contains middleware that controls the flow of requests.
- It includes service providers that bootstrap application services.
- It organizes domain logic into events, listeners, policies, jobs, and rules.
- It follows PSR-4 autoloading, ensuring classes are automatically discoverable.
Laravel places everything related to the application’s internal logic into the app/ folder, keeping the rest of the project clean and modular.
Example: How a Request Moves Through the app/ Folder
To illustrate the power of the app/ folder, here is a simplified flow:
- A request arrives at
/posts. - The request enters the HTTP kernel in
app/Http/Kernel.php. - Middleware is applied.
- The request reaches the route that points to
PostController@index. - The controller method interacts with the
Postmodel. - The model retrieves data from the database.
- The controller returns a response.
This flow demonstrates how the directories inside app/ cooperate.
Sample Full Workflow Code Example
Route
Route::get('/posts', [PostController::class, 'index']);
Controller
public function index()
{
$posts = Post::latest()->get();
return view('posts.index', compact('posts'));
}
Model
class Post extends Model
{
protected $fillable = ['title', 'body'];
}
Blade View (not inside app/, but part of the flow)
@foreach ($posts as $post)
<h2>{{ $post->title }}</h2>
<p>{{ $post->body }}</p>
@endforeach
Leave a Reply