Laravel Events en Listeners 2026: Event-Driven Architecture en Sollicitatievragen

Complete gids voor Laravel Events en Listeners in 2026. Event-Driven Architecture, Observer Pattern, Broadcasting en veelgestelde technische sollicitatievragen met codevoorbeelden.

Laravel Events en Listeners Event-Driven Architecture Diagram

Het event-systeem van Laravel vormt de ruggengraat van een schone, ontkoppelde applicatiearchitectuur. In een tijd waarin microservices en asynchrone verwerking de standaard zijn geworden, maken Events en Listeners flexibele communicatie mogelijk tussen verschillende onderdelen van een applicatie. Laravel 12 heeft dit systeem verder verfijnd met typed Events, verbeterde Broadcasting en native Queue-integratie. Dit artikel behandelt de fundamenten van Laravel Events, geavanceerde patterns en de meest voorkomende sollicitatievragen over dit onderwerp.

Events ontkoppelen businesslogica

Het Observer Pattern, dat ten grondslag ligt aan Laravel Events, maakt het mogelijk om te reageren op acties zonder de triggerende code direct aan te passen. Wanneer een gebruiker zich registreert, kan een event worden verstuurd waarop meerdere Listeners reageren: e-mailverzending, analytics-tracking, CRM-synchronisatie. De registratiecode blijft daarbij slank en gefocust op zijn primaire verantwoordelijkheid.

Events en Listeners aanmaken

Laravel biedt Artisan-commando's voor het snel genereren van Events en Listeners. Een Event vertegenwoordigt een actie die heeft plaatsgevonden in de applicatie, terwijl een Listener op dat event reageert en bijbehorende acties uitvoert.

bash
php artisan make:event OrderPlaced
php artisan make:listener SendOrderConfirmation --event=OrderPlaced
php artisan make:listener UpdateInventory --event=OrderPlaced
php artisan make:listener NotifyWarehouse --event=OrderPlaced

De Event-klasse bevat de relevante data die wordt doorgegeven aan alle Listeners. Laravel 12 ondersteunt typed properties en Constructor Property Promotion voor beknopte code.

php
<?php

namespace App\Events;

use App\Models\Order;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class OrderPlaced
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(
        public Order $order,
        public float $totalAmount,
        public string $currency = 'EUR'
    ) {}
}

De bijbehorende Listener implementeert de handle-methode, die het event als parameter ontvangt. De typedeclaratie maakt IDE-autocompletion en statische analyse mogelijk.

php
<?php

namespace App\Listeners;

use App\Events\OrderPlaced;
use App\Mail\OrderConfirmation;
use Illuminate\Support\Facades\Mail;

class SendOrderConfirmation
{
    public function handle(OrderPlaced $event): void
    {
        Mail::to($event->order->user->email)
            ->queue(new OrderConfirmation($event->order));
    }
}

Event-registratie en Auto-Discovery

Laravel 12 biedt twee methoden voor het registreren van events: expliciete registratie in de EventServiceProvider en automatische discovery. De expliciete methode biedt meer controle en overzichtelijkheid.

php
<?php

namespace App\Providers;

use App\Events\OrderPlaced;
use App\Events\PaymentProcessed;
use App\Listeners\NotifyWarehouse;
use App\Listeners\SendOrderConfirmation;
use App\Listeners\UpdateInventory;
use App\Listeners\SendPaymentReceipt;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        OrderPlaced::class => [
            SendOrderConfirmation::class,
            UpdateInventory::class,
            NotifyWarehouse::class,
        ],
        PaymentProcessed::class => [
            SendPaymentReceipt::class,
        ],
    ];

    public function shouldDiscoverEvents(): bool
    {
        return false; // Expliciete registratie heeft de voorkeur
    }
}

Voor automatische discovery analyseert Laravel de Listener-klassen en bepaalt aan de hand van de handle-methodesignatuur op welke events ze reageren. Deze methode is geschikt voor kleinere projecten of snelle prototyping.

php
public function shouldDiscoverEvents(): bool
{
    return true;
}

protected function discoverEventsWithin(): array
{
    return [
        $this->app->path('Listeners'),
        $this->app->path('Modules/Orders/Listeners'),
    ];
}

Queued Listeners voor asynchrone verwerking

Tijdrovende operaties zoals e-mailverzending of externe API-aanroepen moeten niet synchroon worden verwerkt. Door het ShouldQueue-interface te implementeren worden Listeners automatisch in de queue geplaatst.

php
<?php

namespace App\Listeners;

use App\Events\OrderPlaced;
use App\Services\InventoryService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class UpdateInventory implements ShouldQueue
{
    use InteractsWithQueue;

    public string $queue = 'inventory';
    public int $tries = 3;
    public int $backoff = 60;

    public function __construct(
        private InventoryService $inventoryService
    ) {}

    public function handle(OrderPlaced $event): void
    {
        foreach ($event->order->items as $item) {
            $this->inventoryService->decrementStock(
                $item->product_id,
                $item->quantity
            );
        }
    }

    public function failed(OrderPlaced $event, \Throwable $exception): void
    {
        // Log fout, notificeer admin, trigger compenserende actie
        logger()->error('Inventaris update mislukt', [
            'order_id' => $event->order->id,
            'error' => $exception->getMessage(),
        ]);
    }
}

De configuratie van queue, retry-pogingen en backoff-tijd maakt robuuste foutafhandeling mogelijk. De failed-methode wordt aangeroepen wanneer alle retry-pogingen zijn mislukt.

Model Events en Observers

Eloquent-models dispatchen automatisch events bij CRUD-operaties. Deze Model Events maken het mogelijk om te reageren op databasewijzigingen zonder de controller-code aan te passen.

php
<?php

namespace App\Models;

use App\Events\OrderPlaced;
use App\Observers\OrderObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Model;

#[ObservedBy(OrderObserver::class)]
class Order extends Model
{
    protected $dispatchesEvents = [
        'created' => OrderPlaced::class,
    ];
}

Observer-klassen bundelen alle event-handlers voor een Model op een centrale locatie. Laravel 12 ondersteunt het ObservedBy-attribuut voor declaratieve registratie.

php
<?php

namespace App\Observers;

use App\Models\Order;
use App\Services\AuditLogService;

class OrderObserver
{
    public function __construct(
        private AuditLogService $auditLog
    ) {}

    public function creating(Order $order): void
    {
        $order->order_number = $this->generateOrderNumber();
    }

    public function created(Order $order): void
    {
        $this->auditLog->log('order.created', $order);
    }

    public function updating(Order $order): void
    {
        if ($order->isDirty('status')) {
            $order->status_changed_at = now();
        }
    }

    public function deleted(Order $order): void
    {
        $this->auditLog->log('order.deleted', $order);
    }

    private function generateOrderNumber(): string
    {
        return 'ORD-' . date('Ymd') . '-' . strtoupper(uniqid());
    }
}

Event Broadcasting voor real-time updates

Laravel Broadcasting maakt het mogelijk om server-side events te verzenden naar frontend-clients via WebSockets. Dit is essentieel voor real-time dashboards, chat-applicaties en live notificaties.

php
<?php

namespace App\Events;

use App\Models\Order;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class OrderStatusUpdated implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(
        public Order $order,
        public string $previousStatus,
        public string $newStatus
    ) {}

    public function broadcastOn(): array
    {
        return [
            new PrivateChannel('orders.' . $this->order->user_id),
            new Channel('admin.orders'),
        ];
    }

    public function broadcastAs(): string
    {
        return 'order.status.updated';
    }

    public function broadcastWith(): array
    {
        return [
            'order_id' => $this->order->id,
            'order_number' => $this->order->order_number,
            'previous_status' => $this->previousStatus,
            'new_status' => $this->newStatus,
            'updated_at' => now()->toISOString(),
        ];
    }
}

De frontend kan deze events ontvangen met Laravel Echo en de gebruikersinterface dienovereenkomstig bijwerken.

javascript
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT,
    forceTLS: true,
});

Echo.private(`orders.${userId}`)
    .listen('.order.status.updated', (event) => {
        console.log('Orderstatus gewijzigd:', event);
        updateOrderStatus(event.order_id, event.new_status);
    });

Event Subscribers voor complexe workflows

Event Subscribers maken het mogelijk om meerdere event-handlers in een enkele klasse te groeperen. Dit is nuttig voor domeinspecifieke logica die op verschillende events moet reageren.

php
<?php

namespace App\Listeners;

use App\Events\OrderPlaced;
use App\Events\OrderShipped;
use App\Events\OrderDelivered;
use App\Events\OrderCancelled;
use App\Services\NotificationService;
use Illuminate\Events\Dispatcher;

class OrderEventSubscriber
{
    public function __construct(
        private NotificationService $notifications
    ) {}

    public function handleOrderPlaced(OrderPlaced $event): void
    {
        $this->notifications->sendOrderConfirmation($event->order);
    }

    public function handleOrderShipped(OrderShipped $event): void
    {
        $this->notifications->sendShippingNotification(
            $event->order,
            $event->trackingNumber
        );
    }

    public function handleOrderDelivered(OrderDelivered $event): void
    {
        $this->notifications->sendDeliveryConfirmation($event->order);
        $this->notifications->requestReview($event->order);
    }

    public function handleOrderCancelled(OrderCancelled $event): void
    {
        $this->notifications->sendCancellationNotification(
            $event->order,
            $event->reason
        );
    }

    public function subscribe(Dispatcher $events): array
    {
        return [
            OrderPlaced::class => 'handleOrderPlaced',
            OrderShipped::class => 'handleOrderShipped',
            OrderDelivered::class => 'handleOrderDelivered',
            OrderCancelled::class => 'handleOrderCancelled',
        ];
    }
}

De Subscriber wordt geregistreerd in de EventServiceProvider en groepeert alle gerelateerde handlers logisch.

php
protected $subscribe = [
    OrderEventSubscriber::class,
    PaymentEventSubscriber::class,
];

Klaar om je Laravel gesprekken te halen?

Oefen met onze interactieve simulatoren, flashcards en technische tests.

Sollicitatievragen over Laravel Events

Vraag: Wat is het verschil tussen Events en Observers in Laravel?

Events zijn algemene berichten die overal in de applicatie kunnen worden verstuurd en door willekeurige Listeners kunnen worden verwerkt. Observers zijn specifiek ontworpen voor Eloquent-models en reageren automatisch op CRUD-operaties. Events bieden meer flexibiliteit, terwijl Observers geoptimaliseerd zijn voor model-specifieke logica.

Vraag: Hoe voorkom je dat een Listener de event-propagatie stopt?

Als een Listener false retourneert, worden opvolgende Listeners niet meer uitgevoerd. Om dit te voorkomen moeten Listeners void of een andere waarde retourneren. De volgorde van de Listeners in de array bepaalt de uitvoeringsvolgorde.

Vraag: Wanneer moet ShouldBeUnique worden gebruikt bij Queued Listeners?

ShouldBeUnique voorkomt dat dezelfde job meerdere keren in de queue terechtkomt. Dit is belangrijk voor idempotente operaties zoals e-mailverzending, waarbij duplicaten moeten worden vermeden.

php
class SendWelcomeEmail implements ShouldQueue, ShouldBeUnique
{
    public function uniqueId(): string
    {
        return $this->user->id;
    }
}

Vraag: Hoe test je event-gebaseerde logica?

Laravel biedt Event::fake() voor geïsoleerde tests. Dit voorkomt het daadwerkelijk dispatchen van events en maakt assertions mogelijk.

php
public function test_order_placement_dispatches_event(): void
{
    Event::fake([OrderPlaced::class]);

    $order = Order::factory()->create();

    Event::assertDispatched(OrderPlaced::class, function ($event) use ($order) {
        return $event->order->id === $order->id;
    });
}

Conclusie

Laravel Events en Listeners vormen een krachtig systeem voor ontkoppelde, onderhoudbare applicatiearchitecturen. De combinatie van synchrone events, Queued Listeners en Broadcasting maakt zowel eenvoudige notificaties als complexe Event-Driven Architectures mogelijk. Model Observers vereenvoudigen het reageren op databasewijzigingen, terwijl Event Subscribers gerelateerde handlers groeperen. Voor technische sollicitatiegesprekken is een diepgaand begrip van deze concepten essentieel, aangezien Event-Driven Architecture de standaard is geworden in moderne Laravel-applicaties.

Dagelijkse challenge

Zie jij de bug in Laravel?

Een echt codefragment, een verborgen bug, één poging per dag. Zonder account uit te proberen.

Anthony Fillion-Maillet

Geschreven door

Anthony Fillion-Maillet

Oprichter van SharpSkill

Al meer dan 10 jaar fullstack-ontwikkelaar. Hij leidt SharpSkill en staat in voor alles wat hier verschijnt.

Bijgewerkt op 20 augustus 2026

Tags

#laravel
#events
#listeners
#php
#event-driven

Delen

Gerelateerde artikelen