Przejdź do głównej treści
Grafika przedstawia ukryty obrazek

CQRS i Event Sourcing w PHP

CQRS i Event Sourcing w PHP

Command Query Responsibility Segregation (CQRS) oraz Event Sourcing to wzorce architektoniczne, które umożliwiają efektywne zarządzanie danymi i zwiększają skalowalność aplikacji. W tym artykule przedstawimy ich podstawowe założenia oraz sposób implementacji w PHP.

CQRS – Podział odpowiedzialności

CQRS polega na rozdzieleniu operacji odczytu (Query) i zapisu (Command). Dzięki temu można niezależnie skalować obie części oraz stosować inne modele danych dla odczytu i zapisu.

Przykład CQRS w PHP

Komendy (Commands) i ich obsługa:

class CreateUserCommand {
    public function __construct(
        public string $userId,
        public string $name,
        public string $email
    ) {}
}

class CreateUserHandler {
    public function handle(CreateUserCommand $command) {
        // Tutaj zapisujemy dane użytkownika
        echo "Użytkownik {$command->name} został utworzony.";
    }
}

Zapytania (Queries) i ich obsługa:

class GetUserQuery {
    public function __construct(public string $userId) {}
}

class GetUserHandler {
    private array $users = [
        '1' => ['name' => 'Jan Kowalski', 'email' => 'jan@example.com']
    ];

    public function handle(GetUserQuery $query) {
        return $this->users[$query->userId] ?? null;
    }
}

Event Sourcing – Śledzenie zmian w systemie

Event Sourcing to technika, w której zamiast zapisywać aktualny stan obiektu, przechowujemy sekwencję zdarzeń, które doprowadziły do tego stanu.

Przykład Event Sourcing w PHP

Definicja zdarzeń:

interface Event {}

class UserCreatedEvent implements Event {
    public function __construct(
        public string $userId,
        public string $name,
        public string $email
    ) {}
}

Rejestrowanie zdarzeń:

class EventStore {
    private array $events = [];

    public function append(Event $event) {
        $this->events[] = $event;
    }

    public function getEvents(): array {
        return $this->events;
    }
}

Odtwarzanie stanu obiektu z historii zdarzeń:

class User {
    public function __construct(
        private string $userId,
        private string $name,
        private string $email
    ) {}

    public static function reconstitute(array $events): ?self {
        $user = null;
        foreach ($events as $event) {
            if ($event instanceof UserCreatedEvent) {
                $user = new self($event->userId, $event->name, $event->email);
            }
        }
        return $user;
    }
}

Najprostsza implementacja Event Sourcingu w PHP

$events = [
    'init'      => function($a, &$r) {$r  = $a;},
    'add'       => function($a, &$r) {$r += $a;},
    'subtract'  => function($a, &$r) {$r -= $a;},
];
$store = [
    ['init', 0],
    ['add', 1],
    ['add', 2],
    ['subtract', 5],
    //...
];
file_put_contents('store.json', json_encode($store));

$store = json_decode(file_get_contents('store.json'), true);
$result = null;
foreach ($store as $array)
{
    $name = $array[0];
    $value = $array[1];    
    $callback = $events[$name];
    $params = [$value, &$result];
    call_user_func_array($callback, $params);    
}
var_dump($result);

Zalety i wady CQRS oraz Event Sourcing

Zalety:

  • Skalowalność – Możliwość osobnego skalowania operacji zapisu i odczytu.
  • Lepsza organizacja kodu – Jasny podział na odpowiedzialności.
  • Historia zmian – Event Sourcing pozwala na dokładne śledzenie zmian w systemie.
  • Łatwiejsza obsługa złożonych domen biznesowych – Szczególnie w aplikacjach wymagających wersjonowania danych.

Wady:

  • Złożoność – Wprowadzenie CQRS i Event Sourcingu wymaga dodatkowego kodu i narzędzi do obsługi zdarzeń.
  • Koszty przechowywania danych – Event Sourcing wymaga przechowywania pełnej historii zmian.
  • Trudniejsza nauka i wdrożenie – Wymaga zmiany sposobu myślenia o danych w systemie.

Kiedy stosować CQRS i Event Sourcing?

Kiedy są wskazane?

  • W systemach o wysokiej skalowalności, gdzie odczyt i zapis wymagają niezależnej optymalizacji.
  • Gdy potrzebne jest pełne śledzenie zmian w systemie (np. aplikacje finansowe, systemy audytowe).
  • W złożonych domenach biznesowych, gdzie logika aplikacji jest trudna do odwzorowania w klasycznych modelach relacyjnych.

Kiedy mogą prowadzić do overengineeringu?

  • W prostych aplikacjach CRUD, gdzie klasyczna baza danych wystarcza do obsługi operacji.
  • Gdy złożoność systemu nie uzasadnia dodatkowej warstwy abstrakcji.
  • Jeśli głównym celem jest szybkie dostarczenie rozwiązania, a nie długoterminowa skalowalność.

Podsumowanie

CQRS i Event Sourcing to potężne wzorce architektoniczne, które pomagają w budowaniu skalowalnych i wydajnych systemów. Dzięki CQRS możemy oddzielić operacje odczytu od zapisu, a Event Sourcing umożliwia pełne śledzenie zmian w systemie. W PHP można je zaimplementować za pomocą prostych klas i interfejsów, jak pokazano w powyższych przykładach. Należy jednak rozważyć ich zastosowanie, aby uniknąć nadmiernej komplikacji w projektach, które ich nie wymagają.

13 lutego 2025 20

Kategorie

programowanie

Dziękujemy!
()

Powiązane wpisy


Informacja o cookies

Moja strona internetowa wykorzystuje wyłącznie niezbędne pliki cookies, które są wymagane do jej prawidłowego działania. Nie używam ciasteczek w celach marketingowych ani analitycznych. Korzystając z mojej strony, wyrażasz zgodę na stosowanie tych plików. Możesz dowiedzieć się więcej w mojej polityce prywatności.