Implementeren van Event Driven Design met Symfony

TL;DR

Event Driven Design (EDD) verbetert de modulariteit en schaalbaarheid van je Symfony-applicatie. Gebruik Symfony’s EventDispatcher om events, listeners en event verzending te beheren. Maak een event-klasse, maak een listener-klasse en registreer deze, en verzend events vanuit je controllers of services. Je kunt ook prioriteiten instellen voor de uitvoeringsvolgorde van listeners. EDD kan je applicatie flexibeler, beter schaalbaar en eenvoudiger te testen maken.

Event Driven Design (EDD) is een softwarearchitectuur waarbij applicatiecomponenten reageren op gebeurtenissen (events) om taken uit te voeren. Deze aanpak biedt een hoge mate van modulariteit, flexibiliteit en schaalbaarheid.

Wat is Event Driven Design?

Event Driven Design is een ontwerppatroon waarbij applicaties zijn opgebouwd uit componenten die reageren op gebeurtenissen in plaats van het oproepen van methoden. Dit zorgt voor een losse koppeling tussen componenten, waardoor ze onafhankelijk van elkaar kunnen evolueren en gemakkelijker kunnen worden getest. Bovendien maakt EDD het eenvoudiger om asynchrone en parallelle verwerking te implementeren, wat kan leiden tot betere prestaties en schaalbaarheid.

Symfony’s EventDispatcher-component

Symfony’s EventDispatcher-component is het belangrijkste hulpmiddel voor het implementeren van EDD in je Symfony-applicatie. Met de EventDispatcher kun je events definiëren, listeners registreren en events verzenden. Hier is een overzicht van de belangrijkste concepten:

Event: Een object dat een gebeurtenis in het systeem vertegenwoordigt. Listener: Een object dat reageert op een event door het uitvoeren van een specifieke taak. EventDispatcher: Het centrale object dat events verzendt en listeners aan events koppelt.

Een Event aanmaken

Om een event aan te maken, moet je een nieuwe PHP-klasse maken die uitbreidt van de Symfony\Component\EventDispatcher\Event class. Deze klasse kan de informatie bevatten die relevant is voor de gebeurtenis. Bijvoorbeeld:

namespace App\Event;

use Symfony\Component\EventDispatcher\Event;

class OrderPlacedEvent extends Event
{
    public const NAME = 'order.placed';

    private $order;

    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    public function getOrder(): Order
    {
        return $this->order;
    }
}

Een Listener aanmaken

Om een listener te maken, maak je een nieuwe PHP-klasse met een methode die de gewenste actie uitvoert wanneer het event wordt verzonden. De listener moet zich ook registreren bij de EventDispatcher. Bijvoorbeeld:

namespace App\EventListener;

use App\Event\OrderPlacedEvent;

class OrderNotificationListener
{
    public function onOrderPlaced(OrderPlacedEvent $event)
    {
        // Voer acties uit, zoals het versturen van een e-mail
    }
}

De Listener registreren

Om de listener te registreren, voeg je de volgende configuratie toe aan het services.yaml-bestand:

services:
    App\EventListener\OrderNotificationListener:
        tags:
            - { name: kernel.event_listener, event: order.placed, method: onOrderPlaced }

Een Event verzenden

Om een event te verzenden, injecteer je de EventDispatcher in je service of controller en roep je de dispatch-methode aan met het event-object als argument. Bijvoorbeeld:

namespace App\Controller;

use App\Event\OrderPlacedEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;

class OrderController
{
    private $eventDispatcher;

    public function __construct(EventDispatcherInterface $eventDispatcher)
    {
        $this->eventDispatcher = $eventDispatcher;
    }

    public function placeOrder()
    {
        // Code om een bestelling te plaatsen en een Order-object te maken

        $event = new OrderPlacedEvent($order);
        $this->eventDispatcher->dispatch($event, OrderPlacedEvent::NAME);

        return new Response('Bestelling geplaatst en event verzonden.');
    }
}

Prioriteit van listeners

Als je meerdere listeners hebt die reageren op hetzelfde event, kun je de prioriteit instellen om de volgorde van uitvoering te bepalen. Dit doe je door de priority-optie toe te voegen aan de tag in het services.yaml-bestand:

services:
    App\EventListener\HighPriorityListener:
        tags:
            - { name: kernel.event_listener, event: order.placed, method: onOrderPlaced, priority: 100 }

    App\EventListener\LowPriorityListener:
        tags:
            - { name: kernel.event_listener, event: order.placed, method: onOrderPlaced, priority: -100 }

De listener met de hoogste prioriteit wordt eerst uitgevoerd.

Conclusie:

In dit artikel hebben we gezien hoe je Event Driven Design kunt implementeren in je Symfony-applicatie met behulp van de EventDispatcher-component. Deze aanpak maakt je applicatie flexibeler, beter schaalbaar en gemakkelijker te testen. Bovendien kan het de prestaties verbeteren door asynchrone en parallelle verwerking mogelijk te maken. Begin vandaag nog met het toepassen van Event Driven Design in je Symfony-projecten en ontdek de voordelen voor jezelf!