beginner Step 2 of 15

Routing and Controllers

Laravel Framework

Routing and Controllers

Laravel's routing system maps incoming HTTP requests to controller methods or closures. Routes are defined in routes/web.php for web pages and routes/api.php for API endpoints. Laravel supports all HTTP methods, route parameters, named routes, route groups with middleware, and resource controllers that automatically create CRUD routes. The routing system is one of Laravel's most elegant features, providing a clean and expressive way to define your application's endpoints.

Defining Routes

<?php
// routes/web.php

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

// Basic routes
Route::get('/', function () {
    return view('welcome');
});

Route::get('/about', function () {
    return view('about', ['title' => 'About Us']);
});

// Route with parameters
Route::get('/posts/{id}', function (int $id) {
    return "Post #$id";
});

// Optional parameter with default
Route::get('/users/{name?}', function (string $name = 'Guest') {
    return "Hello, $name!";
});

// Route to controller
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/create', [PostController::class, 'create'])->name('posts.create');
Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
Route::get('/posts/{post}', [PostController::class, 'show'])->name('posts.show');
Route::put('/posts/{post}', [PostController::class, 'update'])->name('posts.update');
Route::delete('/posts/{post}', [PostController::class, 'destroy'])->name('posts.destroy');

// Resource route (creates all 7 CRUD routes in one line!)
Route::resource('posts', PostController::class);

// API resource (excludes create/edit form routes)
Route::apiResource('api/posts', PostController::class);

// Route groups with middleware
Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::resource('settings', SettingsController::class);
});

// Prefix group
Route::prefix('admin')->middleware('auth:admin')->group(function () {
    Route::get('/users', [AdminController::class, 'users']);
    Route::get('/stats', [AdminController::class, 'stats']);
});

Resource Controller

<?php
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;

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

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::latest()->paginate(15);
        return view('posts.index', compact('posts'));
    }

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

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'body' => 'required|string',
            'category' => 'required|in:tech,news,tutorial',
        ]);

        $post = auth()->user()->posts()->create($validated);
        return redirect()->route('posts.show', $post)->with('success', 'Post created!');
    }

    public function show(Post $post)  // Route model binding!
    {
        return view('posts.show', compact('post'));
    }

    public function update(Request $request, Post $post)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'body' => 'required|string',
        ]);

        $post->update($validated);
        return redirect()->route('posts.show', $post)->with('success', 'Post updated!');
    }

    public function destroy(Post $post)
    {
        $post->delete();
        return redirect()->route('posts.index')->with('success', 'Post deleted!');
    }
}
Pro tip: Route model binding (Post $post in method signatures) automatically queries the database by the route parameter and returns a 404 if not found. This eliminates boilerplate lookup code from every controller method. Use Route::resource() to generate all 7 CRUD routes in a single line.

Key Takeaways

  • Define routes in routes/web.php (web) and routes/api.php (API) files.
  • Use Route::resource() to generate all 7 CRUD routes for a resource controller.
  • Route model binding automatically fetches models from the database by route parameters.
  • Named routes (->name('posts.index')) let you generate URLs with route('posts.index').
  • Group routes with middleware(), prefix(), and namespace() for organization and access control.