Создаем CQRS сервис с нуля: Spiral, Symfony Messenger и PHP Attributes | Полное руководство

Поделиться
HTML-код
  • Опубликовано: 6 июн 2024
  • 🚀 Присоединяйтесь к нашему стриму, где мы шаг за шагом создаем CQRS сервис с использованием Spiral Framework, Symfony Messenger и PHP Attributes. Этот стрим будет интересен как начинающим, так и опытным разработчикам, желающим глубже понять архитектуру CQRS.
    🔍 Что мы рассмотрим:
    0:00 Начинаем стрим
    3:00 План стрима
    3:46 Что такое CQRS. Смотрим картинки
    13:00 Создание интерфесов
    17:00 Установка Symfony Messenger
    18:30 Создание перовго теста
    21:56 Создание перовго Command Handler
    25:10 Создание Command Bus
    30:15 Изучаем Symfony Message Bus
    37:00 Создание локатора команд
    51:00 Проверка работы локатора
    51:30 Настройка PHP атрибута
    54:30 Spiral Tokenizer
    1:05:00 Проверка работы локатора с PHP атрибуттами
    1:06:15 Создание Operation Stamp
    1:08:50 Создание Query Bus
    1:12:50 Изучение Middleware для Message Bus
    1:21:40 Доработка локатора Query команд
    1:33:50 Создание первого Query Handler
    1:40:30 Варианты использования Query Bus
    1:43:15 Проверка работы Query Handler
    1:46:15 Про Spiral Prototype
    1:54:05 Для чего нужен Operation Uuid
    1:59:25 Создаем консольную команду
    2:03:00 Transactional Command Bus
    2:11:00 Command Listener
    2:30:30 Советы по передаваемым данным
    Код со стрима находится здесь: github.com/php-fart/cqrs-app
    Ссылка на наш дискорд, где мы проводим стримы и где можно с нами поболтать
    / discord
    Наш канал: t.me/php_fart
    Наши твиттеры:
    / butsch - Pavel Buchnev
    / roxblnfk - Aleksei Gagarin
    #php #spiral #development #symfony
    👍 Если вам нравится контент, подписывайтесь на канал и ставьте лайк. Не забудьте оставить свой комментарий!
  • НаукаНаука

Комментарии • 13

  • @Chepurko87
    @Chepurko87 20 дней назад +1

    Спасибо огромное! Почерпнул для себя массу полезного!

  • @user-jd2xr7bf2t
    @user-jd2xr7bf2t 14 дней назад

    Если создавать пакет CQRS (Command Query Responsibility Segregation), было бы здорово сделать так, чтобы мидлвары выносились в отдельные пакеты, как это реализовано в Tactician.

  • @php-farttime
    @php-farttime  24 дня назад

    Код со стрима выложил в репозиторий: github.com/php-fart/cqrs-app

  • @php-farttime
    @php-farttime  24 дня назад

    Предлагайте идеи для будущих стримов

  • @user-jd2xr7bf2t
    @user-jd2xr7bf2t 14 дней назад +1

    Было бы здорово иметь список мидлваров и возможность указывать, какие из них использовать для конкретной команды через атрибуты. #[middleware list [handler, validator]]

    • @php-farttime
      @php-farttime  14 дней назад

      Да, это можно сделать. Через middleware)

    • @user-jd2xr7bf2t
      @user-jd2xr7bf2t 14 дней назад

      @@php-farttime я такое уже писал для своего Bus Удобно. И решает проблему (Igor Markin
      ​​InMemoryCommandBus, KafkaCommandBus и тд)

    • @user-jd2xr7bf2t
      @user-jd2xr7bf2t 14 дней назад

      Дополнение.. #[middleware list [ ValidatorMiddleware, TransactionMiddleware, EventMiddleware,Handler]]
      ValidatorMiddleware: проверяет команду на соответствие требованиям.
      TransactionMiddleware: оборачивает выполнение команды в транзакцию.
      EventMiddleware: обрабатывает события после выполнения команды.
      HandlerMiddleware: выполняет саму команду, вызывая соответствующий обработчик.
      порядок запуска миделверов будет порятку их добавление в list

    • @user-jd2xr7bf2t
      @user-jd2xr7bf2t 14 дней назад

      Функция установки мидлваров:
      private function setMiddlewares(object $message) {
      $reflectionClass = new \ReflectionClass($message);
      // Получаем аннотации [Middlewares]
      $middlewaresAttributes = $reflectionClass->getAttributes(Middlewares::class);
      if (!empty($middlewaresAttributes)) {
      // Получаем первую аннотацию [Middlewares]
      $middlewaresAttribute = $middlewaresAttributes[0];
      // Извлекаем аргументы аннотации
      $middlewaresArguments = $middlewaresAttribute->getArguments();
      // Теперь у вас есть доступ к массиву промежуточных слоев
      $middlewaresList = $middlewaresArguments['list'];
      foreach ($middlewaresList as $middlewareName) {
      $this->middlewares->addMiddleware($middlewareName);
      }
      }
      }

    • @user-jd2xr7bf2t
      @user-jd2xr7bf2t 14 дней назад

      Мой пример команды:
      #[Middlewares(list: [ValidationBusMiddleware::class, CommandHandlerMiddleware::class])]
      #[Handler(className: CreateUserHandler::class)]
      #[Validation(className: CreateUserValidator::class)]
      final class CreateUserCommand implements ICommand {
      public function __construct(
      #[Assert\NotBlank]
      public readonly string $uuid,
      #[Assert\NotBlank]
      public readonly string $login,
      #[Assert\NotBlank]
      #[Assert\Email(message: 'The email {{ value }} is not a valid email.')]
      public readonly string $email,
      #[Assert\Length(min: 6)]
      #[Assert\NotBlank]
      public readonly string $password,
      #[Assert\NotBlank]
      public readonly string $name,
      #[Assert\NotBlank]
      public readonly string $gender,
      ) {
      }
      }

  • @user-jd2xr7bf2t
    @user-jd2xr7bf2t 14 дней назад

    Было бы проще заменить dispatchMany на middlewareEvent, который по имени команды подключает соответствующие мидлвары, а затем запускает их. Эта мой пример