Paulund
2024-03-10 #laravel

New Laravel 11 Features

Laravel 11 comes with a load of new features, the focus of this release has been to streamline the application structure, per-second rate limiting, health check routing, encryption key rotation, queue testing improvements, new artisan commands, and more.

There is also a new Laravel tool being release called Laravel Reverb, a scalable WebSocket server.

PHP Version

Laravel 11 requires a minimum version of PHP 8.2.

Application Structure

The application structure has been streamlined to make it easier to understand and navigate.

When you start up a new application it will look different to previous versions. But it has backward compatibility so you can still use the old structure if you want.

The new structure will make it easier to get a default application up and running faster, while keeping your code clean. But also at the same time allow you to expand the application by manually adding the old folders back in.

Application Bootstrap File

The bootstrap/app.php file has been simplified and now only contains the code to create the application instance. From here you can customise your application by changing the routing, middleware, service providers and exceptions.

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

Service Providers

In previous versions of Laravel the service provider folder will contain 5 different service providers but in Laravel 11 this has been reduced to just 1 the AppServiceProvider.

If you'd like to register events or authentication you can now do this from the AppServiceProvider.

Middleware

In previous versions of Laravel application it will come pre loaded with multiple middleware files in your HTTP folder, these have now be taken out and moved into the framework itself. If you'd like to customise how these work you can do so from the bootstrap/app.php file.

This also means that there isn't a need for the HTTP kernel file anymore.

Scheduling

There is a new Schedule facade that allows you to register your commands inside the routes/console.php file. This means that the console kernel file is no longer needed.

use Illuminate\Support\Facades\Schedule;

Schedule::command('inspire')->everyMinute();

Exception Handling

Previously there was a global exception handler class but keeping the theme of reducing the amount of files you have in your application to interact with the framework, this exception handling has now been moved into the bootstrap/app.php file.

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->dontReport(CustomException::class);

    $exceptions->reportable(function (InvalidCustomerException $e) {
        // ...
    });
})

Base Controller

The base controller will no longer extend the Controller class, and it will no longer have the Authorisation and Validate request traits, therefore if you want this functionality for all requests then you'll need to add these back in.

Application Defaults

A default Laravel application will now use SQLite as the default database driver. This database driver will also be used for sessions, cache and queues. The reason for this change is the speed of getting a new laravel application up and running without having to install a new database application.

There has been issues with using the database as the queue driver in the past but a lot of work has been done to improve this functionality so much that it can be used in production.

Per Second Rate Limiting

Laravel can now support a per second rate limiter for all rate limiters, previously these were only available per minute.

This can be used to limit HTTP requests and queued jobs.

Laravel Rate Limiting

Health Check Routing

Laravel 11 has introduced a new health check routing feature this is defined in the bootstrap/app.php file.

->withRouting(
    web: __DIR__.'/../routes/web.php',
    commands: __DIR__.'/../routes/console.php',
    health: '/up',
)

This can be used by your health monitoring services or by services like Kubernetes liveliness and readiness probes.

When this endpoint is hit it will dispatch a DiagnosingHealth event that will allow you to run additional checks if you need to. For example you might want to also check your Redis cache server is responding correctly.

This route will also return a view of resources/health-up.blade.php if the application is healthy. Therefore if you want to customise this view you can do so from this view.

Eager Loading Limit

There is a new limit method that can be used to limit the number of relationships that are eager loaded.

$posts = Post::with([
    'comments' => fn ($query) => $query->limit(10)
])->get();

This will limit the number of comment that are loaded to 10. In previous version when this didn't exist the comments relationship could grow to a large number and slow down your application.

The idea for this comes from this package eloquent-eager-limit, if you're on older versions of laravel you could implement this package to get the same functionality.

Dumpable Trait

There is a new dumpable trait that can be used to dump the class data during debugging.

class Stringable implements JsonSerializable, ArrayAccess
{
    use Conditionable, Dumpable, Macroable, Tappable;
 
    str('foo')->dd();
    str('foo')->dump();
}

Encryption Key Rotation

Laravel uses the APP_KEY to encrypt things like cookies, sessions, and other sensitive data. This key should be rotated regularly to ensure that if it is compromised it can't be used to decrypt any data. This has previously been a hard thing to do and will mean that users will be logged out of your application when you rotate the keys. This also makes it difficult to handle previously encrypted data by your application.

Laravel now comes with a APP_PREVIOUS_KEYS environment variable that can be used to store comma separated list of the previous keys that have been used to encrypt data. This means that when you rotate the key you can still decrypt the old data.

When you encrypt new values Laravel will use your APP_KEY but when you decrypt it will first try with APP_KEY and then try with the previous keys.

This will stop users from being logged out of your application when you rotate the keys and will also allow you to handle previously encrypted data.

Command Line Prompt Validation

Previously you can add prompts to your artisan commands but you couldn't validate the input. Laravel 11 now comes with a validate parameter that can be used to validate the input.

$name = text('What is your name?', validate: [
    'name' => 'required|min:3|max:255',
]);

It uses the default Laravel validation rules and will throw an error if the input doesn't match the rules.

Additional Queue Testing

There has been new functionality added to your queue testing such as ensuring that a job has been added to the queue with a delay.

use App\Jobs\ProcessPodcast;
$job = (new ProcessPodcast)->withFakeQueueInteractions();
$job->handle();
$job->assertReleased(delay: 30);

New Artisan Commands

With the new quicker application structure there has been a few new artisan commands added to help you with your development.

php artisan make:class
php artisan make:enum
php artisan make:interface
php artisan make:trait

Model Cast Method

There is a new cast method that can be used to cast your model attributes to a specific type.

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsCollection::using(OptionCollection::class),
                  // AsEncryptedCollection::using(OptionCollection::class),
    ];
}

Once Function

There is a new once function that can be used to ensure that a callback is only executed once. This will cache the result of the callback for the duration of the request.

function random(): int
{
    return once(function () {
        return random_int(1, 1000);
    });
}

random(); // 123
random(); // 123 (cached result)
random(); // 123 (cached result)

This was once a Spatie package but has now been added to Laravel framework.

Laravel Revert

Laravel Revert is a new tool that has been released with Laravel 11. It is a scalable WebSocket server that can be used to build real-time applications.

This can be integrated with Laravel Echo and can be used to build real-time applications that require real-time communication.

Reverb supports horizontal scaling via Redis's publish / subscribe capabilities, allowing you to distribute your WebSocket traffic across multiple backend Reverb servers.

Laravel Reverb

Support Policy

| Version | PHP (*) | Release | Bug Fixes Until | Security Fixes Until | | --- | --- | --- | --- | --- | | 9 | 8.0 - 8.2 | February 8th, 2022 | August 8th, 2023 | February 6th, 2024 | | 10 | 8.1 - 8.3 | February 14th, 2023 | August 6th, 2024 | February 4th, 2025 | | 11 | 8.2 - 8.3 | March 12th, 2024 | September 3rd, 2025 | March 12th, 2026 | | 12 | 8.2 - 8.3 | Q1 2025 | Q3, 2026 | Q1, 2027 |

(*) Laravel 11 supports PHP 8.2 and 8.3.

Conclusion

There has been a lot of new features added to Laravel 11, the main focus has been to streamline the development of a new application.

This is for the hope that Laravel will be lighter to use for smaller, quicker applications.

The improvements to using SQLite and making this the default database will make this very easy to use for smaller MVP like applications that you want to get up and running quickly. Making Laravel a very good option for a quick MVP of a new idea, plus gives you the ability to expand on the functionality as your application grows.

For quicker applications in the past I may have reached for Next.js or NuxtJS but some of these improvements will make me consider using Laravel for these quicker smaller applications while at the same time making it my go framework for larger applications. In my opinion this is the intention of this Laravel version.