Back to Blog
LaravelPHPBackendTutorial

Getting Started with Laravel 11

March 20, 2024
3 min read
Getting Started with Laravel 11

Getting Started with Laravel 11

Laravel 11 brings exciting new features and a streamlined developer experience. In this guide, we'll set up a project from scratch, explore the new directory structure, and build a simple API endpoint.

Prerequisites

Before diving in, make sure you have the following installed:

  • PHP 8.2+ — Laravel 11 requires PHP 8.2 as the minimum version
  • Composer — PHP dependency manager
  • Node.js 18+ — For frontend asset compilation
  • MySQL 8.0+ or PostgreSQL 15+ — Database

Installation

Create a new Laravel 11 project using Composer:

composer create-project laravel/laravel my-app
cd my-app
php artisan serve

Your application will be running at http://localhost:8000.

The New Directory Structure

Laravel 11 introduced a significantly simplified directory structure. The app/Http/Middleware directory is gone — middleware is now registered in bootstrap/app.php:

// bootstrap/app.php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            'admin' => \App\Http\Middleware\EnsureIsAdmin::class,
        ]);
    })
    ->create();

Building a Simple API

Let's create a Task API with a model, migration, and controller.

Step 1: Generate the Model

php artisan make:model Task -mcr

This creates the model, migration, and resource controller in one command.

Step 2: Define the Migration

// database/migrations/xxxx_create_tasks_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description')->nullable();
            $table->enum('status', ['pending', 'in_progress', 'completed'])->default('pending');
            $table->timestamp('due_date')->nullable();
            $table->timestamps();
        });
    }
};

Step 3: Create the Controller

// app/Http/Controllers/TaskController.php
namespace App\Http\Controllers;

use App\Models\Task;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class TaskController extends Controller
{
    public function index(): JsonResponse
    {
        $tasks = Task::orderBy('created_at', 'desc')->paginate(15);
        return response()->json($tasks);
    }

    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
            'status' => 'in:pending,in_progress,completed',
            'due_date' => 'nullable|date|after:today',
        ]);

        $task = Task::create($validated);
        return response()->json($task, 201);
    }

    public function show(Task $task): JsonResponse
    {
        return response()->json($task);
    }

    public function update(Request $request, Task $task): JsonResponse
    {
        $validated = $request->validate([
            'title' => 'sometimes|string|max:255',
            'status' => 'in:pending,in_progress,completed',
        ]);

        $task->update($validated);
        return response()->json($task);
    }

    public function destroy(Task $task): JsonResponse
    {
        $task->delete();
        return response()->json(null, 204);
    }
}

Step 4: Register Routes

// routes/api.php
use App\Http\Controllers\TaskController;

Route::apiResource('tasks', TaskController::class);

Key Improvements in Laravel 11

FeatureLaravel 10Laravel 11
Min PHP Version8.18.2
Directory StructureFullSimplified
MiddlewareKernel.phpbootstrap/app.php
Config Files15+ filesOn-demand publish
Health CheckManualBuilt-in /up route

What's Next?

  • Add authentication with Laravel Sanctum
  • Implement Queues for background jobs
  • Set up Laravel Reverb for real-time features

Stay tuned for Part 2 where we'll add authentication and deploy to production!