SyntaxStudy
Sign Up
Laravel Route Groups and Middleware
Laravel Beginner 1 min read

Route Groups and Middleware

Route groups allow you to share attributes — such as middleware, prefixes, and namespace prefixes — across a set of routes without repeating them. A group is defined with Route::group() or the fluent Route::middleware()->prefix()->group() style. This keeps route files organized and eliminates duplication when many routes share the same access control or URL prefix. Middleware acts as a filter layer for HTTP requests entering your application. Laravel ships with middleware for authentication (auth), guest access (guest), CSRF verification (VerifyCsrfToken), and more. You can attach middleware to individual routes or to entire groups. Custom middleware is created with php artisan make:middleware and registered in app/Http/Kernel.php. Route model binding is a powerful convenience that automatically resolves Eloquent models from route parameters. When a controller method type-hints an Eloquent model and the route parameter name matches the binding key, Laravel fetches the record automatically and returns a 404 if it is not found. This eliminates boilerplate findOrFail() calls in every controller method.
Example
<?php
// routes/web.php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Admin\DashboardController;
use App\Http\Controllers\Admin\UserController;
use App\Http\Controllers\PostController;

// Group with middleware and prefix
Route::middleware(['auth', 'verified'])->prefix('admin')->name('admin.')->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
    Route::resource('users', UserController::class);
});

// API versioning group
Route::prefix('api/v1')->middleware('throttle:60,1')->group(function () {
    Route::get('/posts', [PostController::class, 'index']);
    Route::post('/posts', [PostController::class, 'store']);
});

// Route model binding — Laravel auto-fetches Post by {post} id
Route::get('/posts/{post}', function (\App\Models\Post $post) {
    return $post; // 404 if not found automatically
});

// Custom binding key (use slug instead of id)
Route::get('/posts/{post:slug}', [PostController::class, 'show']);

// Fallback route (matches any undefined URL)
Route::fallback(function () {
    return response()->view('errors.404', [], 404);
});