Это видео недоступно.
Сожалеем об этом.
CQRS (Query & Command Multiple Buses) | Symfony PHP
HTML-код
- Опубликовано: 7 мар 2022
- Как реализовать CQRS подход в Symfony приложении, используя шины команд и запросов (Query & Command Multiple Buses).
Telegram: t.me/alejandroyakovlev
Уроки, менторство - boosty.to/sashokgorshok
Уроки, менторство - boosty.to/sashokgorshok
Очень познавательный урок, как и все остальные на этом канале. Хотелось бы больше видео.
Круто! Спасибо большое за работу 🙂👍
Круто, продолжай!
Спасибо! Ты молодец!!!
Алехандро - уже 5 дней прошло - а вкусного видео до сих пор нет )))) Хотя в репо пару интересных вещей уже есть...... Ждемс
Записал, монтирую, в скором времени будет на канале!
Спасибо за поддержку! ))
@@AlejandroYakovlev Если не секрет сколько лет, может и месяцев ты "шёл" к правильной архитектуре? Ты самоучка или хороший учитель был? Сколько у тебя лет опыта? P.s. Прости за то что тыкаю, просто мне кажется это более дружелюбно. Если ты против буду Выкать. Мне не сложно.
В моём случае хорошие учителя были те, которые показывали как делать не надо :)
Главный вопрос здесь, полагаю, не "сколько времени", а "каким образом". Ведь один человек за месяц может освоить то, что другой изучает годами. Здесь важны и условия и стимул. Безусловно нужен хороший ментор, который на голову выше во многих вопросах, не только технических. И в роли ментора хорошо выступают не только тех лиды, но и книги, статьи и видеоматериалы.
Чтобы развиться в архитектурном направлении нужная хорошая почва для практики и разносторонний технический бэкграунд. У меня опыт разработки на данный момент 7 лет. Но вопросами архитектуры я занимаюсь только последние 3 года.
Ты бог!
Все мы боги :)
Спасибо за видео. Я уже давно работаю программистом, но как-то не встречал данный термин и заинтересовало, решил посмотреть. Подход интересный, чем то напомнило GraphQL с его query и мутациями, в плане разделения запросов на чтение и запись или выполнение команд. Единственное (предыдущие видео не смотрел, может там было объяснение) для новичков наверно не особо понятен принцип создания такой структуры приложения, нужно бы про domain driven design рассказать. Еще есть вопрос - если в микросервисе подразумевается наличие только команд, то есть все запросы это обратись к api и дай мне ответ что все окей или обратись к api и кинь в очередь сообщение что все окей. Вот в таком случае есть смысл использовать данный паттерн? Или это избыточно?
Спасибо большое за видео, но не очень понятно как с данным подходом реализовать непосредственно запись в одно место, а чтение из другого при наличии чистой архитектуры.
Т.е у нас есть интерфейс репозитория где мы вызываем методы для чтения и записи, и на уровне юз кейсов мы не мыслим понятиями куда конкретно запишется и от куда конкретно прочитается.
И получается, что если мы хотим иметь отдельное представление для чтения, то мы уже внутри конкретной имплементации репозитория реализуем запись в одно место, а чтение из другого и непонятно чем тут помогает разбиение на разные шины, если разделение логики чтения/записи происходит в репозитории. Мы фактически можем сделать тоже самое и без шин и разделения сервисов на команды и запросы.
Выглядит так, будто разбиение на разные шины нужны просто чтобы визуально разделить друг от друга команды и запросы и возможность регулировать синхронность/асинхронность в них
Автор молодец, отличная демонстрация знаний работы месенджера, но считаю что тема совсем не раскрыта (и раскрыта не в тему). Нужен реальный пример из жизни, когда это стало бы необходимым. Плюс, CQRS как раз таки применяют для того, что бы доменный интерфейс репозитория не разбухал от методов вроде findByEmailAndRegisterDate() или findAllAndHereStarsOrderedByCreationDate($limit = 10)...
Очень круто, мне понравился подход CQRS в целом подход понятен и интересен. Вопрос с такими штуками как RabbitMQ и как это все использовать вместе и в каких случаях было бы очень интересно, особенно на примере микросервисного подхода, просто у меня не было опыта работы с сервисами очередей и вот то, что сделано в этом видео это по сути оно и есть?
Это не совсем про очереди, но очень близко :)
Будет отдельный ролик на тему очередей.
Спасибо за видео. А что за приложение ты делаешь? Почему в браузере не показываешь? Мне очень интересно но не все понимают.
В этом уроке еще не было конкретной тематики приложения. Позже в телеграм канале общим голосованием (t.me/alejandroyakovlev/15) было решено делать приложение по оценке навыков сотрудников.
Привет, Саша, хочу задать тебе вопрос - Telegram не находит тебя - как с тобой связаться?
t.me/alex6ndr
1 - А почему ты в FindUserByEmailQueryHandler возращаешь UserDto, а не саму сущность User?
2 - И почему в конструктор CreateUserCommand не передать сразу готовую дто либо саму сущность?
3 - На каком уровне и где происходит логирование, допустим, такой пользователь уже существует UniqueConstraintViolationException, можно логировать в CreateUserCommandHandler?
1. DTO более гибкая, и может содержать более широкий перечень свойств и в совершенно инос представлении. Плюс приитаком подходе сущность будет более защищенной от случайных мутаций.
2. Можно DTO передать, это особенно полезно, когда параметры в избытке.
3. На прикладном слое.
всё очень классно, но очень тихо
Если вы добавляете Пльзователю Profile , по какому полю вы их свяжите ulid int or ulid ulid? Хочу понять в User вы используете ulid из каких соображений, и вообще когда вы его используете? У ulid - есть минус, он не читаем человеком :) .
Уроки хороши.
Главнное преимущество в стравнении с INT auto increment , генерируеммым на стороне БД - это заранее известное значение идентификатора до записи в БД, которое позваляет строить агрегаты, отношения, генерировать события предметной области и пр.
Поюс ulid уникальный в глобальном масштабе, что не скажешь о int, часто уникальный в пределах таблицы.
Отношения вяжутся по ulid.
@@AlejandroYakovlev А для Profiler (продолжая вопрос User Profile , One To One) Вы бы создавали свой ulid или сразу бы создовали с тем же , что и User?
Однозначно свой ulid. Мухи отдельно, котлеты отдельно. Проще понимать структуру, когда идентификация сущности не зависит от внешних связей. Особенно если сущность со временем может превратиться в отдельный самостоятельный агрегат.
Спасибо, клёво. Вопрос 1) зачем нужны ДТО-шки. 2) Зачем так заморачиваться с папками Сущности в проекте? В другое место класть, в чем профит? 3) Смысл CQRS поняен, но то что ты сделал в Симфонии - реализация не очень.... 4) Ссылки пожалуйста добавь на Мартина Фаулера
А вы не все видео посмотрели? Вроде в видео о архитектуре поясняется.
@@fitter2boss72 честно, начал с конца как носподин Ютуб пожелал, дошёл до начала, и все равно это все мутно. Мы можем придумать вместо мопеда мотоцикл, он поедет быстрее, но архитектура все равно мопеда, просто рама потолще, да мотор с тормозами помощнее, в целом все тоже "колесо"
@@maksims.alekseicevs Для домашнего проекта эта архитектура оверхэд, но для сложных, где вам может быть понадобиться маштабируемость и микросервисы там это зайдет. Уже одно то, что бизнес логика может быть просто скопирована на другой фреймворк дорогого стоит.
И еще добавлю, видео о домашних проектах "без" архитектуры (или с простой архитектурой) дофига, а о "взрослых" кот наплакал, я даже не вспомню никого, разве Дмитрия Е.
1. DTO - для передачи данных, не более.
2. Сущности имеют прямое отношение к предметной области и находятся на слое, где эта предметная область представлена.
3. Опиши более конструктивно, что ты имеешь ввиду с примером альтернативной реализации.
4. Ссылки указаны в видео.
@@fitter2boss72 все живут сегодняшним днем, тяп ляп и в продакшЭн. Платят же за то что работает, а не за правильную архитектуру )) я не приверженец RAD, просто если вокруг посмотреть, так и есть. Тем более я считаю Симфонию Enterprise Framework. Спасибо за разеснение, пожалуй копи пайсте папки в другой фрейм самый везкий аргумент.
Отличные видео. Но у меня вопрос - должен ли Command возвращать что-нибудь (тут возвращает) и почему в хендлер передается не "CommandInteface $command", а "CreateUserCommand" сразу
Command по сути является DTO. Её хэндлер может возвращать результат работы: исключения, список ошибок, id созданной сущности.
CreateUserCommandHandler на вход принимает команду, как раз таки реализующую CommandInterface.
@@AlejandroYakovlev когда команда возвращает ид созданной записи - это ломает суть асинхрнности cqrs. Правильнее было бы при создании юзера передавать заранее сгенерированный ид
Damain? Шторм не ругался?
Почему null но не исключение? Какой профит даёт бесконечное поднятие null? Чем плохо кинуть эксепшен из репозитория, ведь на уровне репозитория это исключительная ситуация, т.к. метод обещает (по названию) вернуть пользоователя, но не может этого сделать (по неизвестной причине).
Здесь вопрос удобства, места и времени. Попробуйте и так, и этак. В одном месте проще исключение кинуть, в другом null. В одном случае вам придется try catch обмазываться, в другом if. Где-то удобно контекст в исключении тащить, где-то в CommandResult. Вообще очень много нюансов. Действуйте по наитию.
Не понял главного. Зачем мы это делаем?
Привет)) Видео класс. Как с тобой можно связаться по Event Storming?
t.me/alex6ndr
Как CQRS реализовать Update в котором присутствует и чтение и запись?
В виде команды.
Прежде всего скажу, что отличные уроки! А потом уже спрошу почему вы добавляете ключевое слово interface к интерфейсам, ведь это считается сейчас очень дурным тоном?
Благодарю за отзыв! :)
Если Вы о венгерской нотации, то она как лакарство - в малых дозах полезно, в больших - яд. Я являюсь противником избыточной информации в нейминге, если язык предполагает типизацию.
Преимущества в случае с суффиксом Interface:
1. В Symfony так принято, если посмотреть на документацию.
2. Autocomplete в IDE при вводе Interface при создании класса через конструктор - лайфак, ускоряющий жизнь на несколько секунд.
3. Наглядность и определенность - мы явно видим, что внедряется интерфейс.
Пробовал:
Foo - интерфейс
FooBarImpl - реализация.
Тоже неплохо.
В общем, как договоритесь в команде, так и делайте. Дело вкуса и удобства :)
Где это считается "очень дурным тоном"? Где-то считается, а где-то нет. Вопрос весьма спорный. Мне например норм сразу видеть, что это интерфейс (с суфиксом), кто-то любит в стиле C# обзывать с заглавной латинской i (например IUserRepository). Это чисто вкусовщина. Ой не туда вы замечания делаете, совсем не туда....
А где юзкейзы? В чистой архитектуре они должны быть.
Плюс в чистой архитектуре существует не гласное правило хорошего тона - метод, либо ничего не возвращает, либо должен вернуть ошибку, либо должен вернуть сущность. Это значит, что метод не должен возвращать null. И не важно, относиться этот метод к репозиторию, или к адаптеру, или же к сервису юзкейза. А отсюда соответственно следует, что ошибки бизнес логики - это ошибки, а не исключительные ситуации. То есть метод может вернуть либо ошибку, либо полезность, чаще всего сущность. В других языках для этого есть монады result или either, или есть возможность вернуть кортеж вида {result(:ok/:error), some_value}.
Видео интересное. Но считаю, что интерфейс для репозитория не нужен
Еще раз прочитай про гексогональную архитектуру портов и адаптеров. Application Layer должен основываться на интерфейсах Domain Layer, а Infrastructure Layer хранит в себе реализации интерфейсов из Domain Layer. Попробуй вначале построить логику своего приложения исключительно на доктриновском репозитории и магических findBySomething, либо findBy(Criteria) или em->persist() em->flush(), а потом заменить DoctrineUserRepository на какой нить TarantolUserRepository, посмотрю я на тебя...
Почему-то в начале кажется, что гемороя с этими тестами больше чем от того с чем они призваны справляться :(
Видео хорошее, но для новичков можно было бы объяснить CQRS без излишеств, а тут все зачем-то усложнено в 10 раз, и много лишнего. Вообще можно было все в три файла уместить.
Расскажите, пожалуйста, какие моменты считаете излишествами?
Нужно еще настроить БД для CQRS, чтобы запросы шли на слэйв, а комманды на мастер.
Всё круто, но о PSR при форматировании лучше не забывать. 😅
Удобство разработки?) Норм шутка)
а потом удивляются зачем Ларавел стал популярным из всех
Симфони отстой для недалёких.
Добро пожаловать