Use Cases модуля аутентификации

Анализ Use Cases взаимодействия с модулем аутетнификации. Выделение команд Command и запросов Query. Принцип CQS разделения операций.

Комментарии (23)
Arunas
2020-01-21 16:54

Спасибо. Очень интересно.

Ответить
Bondarenko Alexandr
2020-01-21 17:12

Спасибо, Дмитрий! Хотел бы посмотреть в вашем исполнении на реализацию подобной ситуации: пользователь регистрируется в контексте аутентификации с ролью покупателя, в контексте покупателей также создается сущность с данными покупателя. Эти данные относятся только к предметной подобласти покупателей ( и не относятся к контексту аутентификации ). Ситуация гиппотетическая. Ну и вообще очень интересно было бы посмотреть на различные вариации интеграции ограниченных контекстов.

Ответить
fedot
2020-01-22 07:34

Это вполне реальная ситуация, у покупателя куча полей, которые не нужны пользователю, например в битрикс так сделано, думаю Дмитрий поступит аналогично, когда дойдет до аукциона.

Ответить
Ruslan
2020-01-21 18:18

Спасибо. Хотелось бы чуть сторонней информации о процессе "проверка приложения" на Facebook. И еще предположим, что нам ТРЕБУЕТСЯ майл пользователя, а Facebook API не всегда его предоставляет, выдает токин и всё, что будем делать в таком случае?

Ответить
kafkiansky
2020-01-22 12:20

Запрашивать почту дополнительно.

Ответить
Ruslan
2020-01-22 18:42

Это был намек на добавления этого процесса.

Ответить
Александр
2020-01-21 20:59

Заметил, что изменение скорости воспроизведения видео не работает. Смотрю с мобильного браузера chrome android

Ответить
Алексей
2020-01-23 10:13

Непонятно почему DTO назвали Command, ведь Command должен что-то изменять, а DTO объект просто содержит данные.

Ответить
Deworker Pro
2020-01-24 07:36

Есть команда на изменение и её обработчик. Мы отправляем команду с описанием того, что нам нужно сделать. И система её выполняет. Такое именование используется в подходе с Command Bus, где команды даже могут сериализоваться и отправляться в очередь для выпонления в фоне.

Это не классический паттерн Command, где сам объект команды содержит методы execute() и undo(). У нас такой подход будет неудобен, так как обработчику понадобятся зависимые объекты и его конструктор будет ими занят.

Ответить
Arunas
2020-01-23 19:50

будет ли очередь (Rabbit или Queue) ?

Ответить
Дмитрий Ориховский
2020-01-24 07:27

В описании курса написано "С WebSocket-интерактивом и очередями на RabbitMQ"!

Ответить
Arunas
2020-01-24 09:21

да да, спс., незаметил ..:)

Ответить
Алексей
2020-01-24 16:27

Если именование Handle ещё не очень критично, так как мы его фактически нигде не вызываем, обычно это command bus, то вот с Command все сложнее. По всему коду и тестам у нас будут new Command(), чтобы понять что это за команда, надо либо полезть в use, либо делать в use алиас, либо перейти в класс команды. Всё это неудобно. Не лучше ли избавиться от папки c названием команды и перенести это в название класса, например, JoinByEmailRequestCommand, JoinByEmailRequestHandler. С одной стороны длинные названия классов, но с другой стороны в сто раз код читабельнее становится

Ответить
Deworker Pro
2020-01-24 19:42

Можно как угодно. Становится читабельнее, но не писабельнее. А так да, если вдруг потребуется использовать две команды в одном классе (что вряд ли произойдёт), то можно использовать алиасы.

Ответить
Александр
2020-01-28 22:45

Очень полезный урок, спасибо.

Хотелось бы узнать а как транзакции реализуются при таком подходе, предположим зарегистрировали пользователя (пользователь нужен сразу в контексте авторизации, автора и покупателя), это посути записи в три отдельных контекста.

Пользователь валидный только если он присутствует во всех трёх контекстах одновременно (по разным причинам).

Нам по сути по одному действию (регистрации) нужно кинуть три команды сразу. Две у нас выполняется, третья крашится. По условию пользователь не валидный, что делать в таком случае? В транзакцию это дело не завернешь, ну и две предыдущие нужно откатить как то ?

Ответить
Deworker Pro
2020-01-31 07:35

Это делается через саги, подписываемые на доменные события.

Ответить
Igor
2020-02-06 20:07

Спасибо за уроки. Появилось пару вопросов. "Модуль" Auth это конекст из ддд терминологии? Содержимое папки Commands это Application Services или Domain Services?

Ответить
Deworker Pro
2020-02-09 12:24

Да, разбиваем на модули по контекстам. А горизонтальное разбиение такое:

Framework:
    Web\App, Console\App
Ui:
    Http\Action, Console\Command
Application:
    Command
    Query
Domain:
    Entity
    Service
Ответить
Максим
2020-03-11 00:35

Здравствуйте. Спасибо за толковый подход!) А почему структура текущего проекта не такая? Она избыточна?

И ещё один вопрос интересный. Есть мероприятия, на которые регистрируются участники. Сейчас это модуль мероприятий. Но регистрации бывают разных типов и у каждого типа своя регистрация. Я разделил все так:

Event/Registrations/Competition Event/Registrations/Battle ... другие регистрации (приобретение билетов....)

Правильно ли я сделал? Либо регистрацию вынести в отдельный модуль. А в самом модуле только использовать ID мероприятия.

Ещё, как вариант, разделить Event по типам:

Event/Competition/Registration Event/Battle/Registration

И тогда создание мероприятий будет в разных сущностях и хранится в разных таблицах. В яндекс афише тоже есть подобное. И, как мне кажется, там всё разделено. Даже приобретение билетов...

Ответить
Deworker Pro
2020-03-12 09:52

Если делать полное разбиение по слоям, то нужно ещё и отделить слой инфраструктуры:

Application
    Command
    Query

Domain
    Entity
        class Id
        interface UserRepository
    Service
        interface PasswordHasher
    interface Flusher

Infrastructure
    Entity
        class IdType
        class DoctrineUserRepository implements UserRepository
    Service
        class CryptPasswordHasher implements PasswordHasher
    class DoctrineFlusher implements Flusher

в который вынести всю работу с Doctrine и прочие "грязные" реализации, а в Domain оставить только чистые сущности и чистые доменные интерфейсы.

Так что да, такое горизонтальное разбиение на папки часто избыточно.

Ответить
Максим
2020-03-12 10:57

Видел такое разбиение у вас вhttps://github.com/ElisDN/rabbit-demo-spa. Сейчас проект и подход похожий, поэтому спросил) Понял. Спасибо за ответ!)

Ответить
Deworker Pro
2020-03-12 09:58

Если регистрация производится одинаково, то вынести в Registration c EventId.

Если на Competition и Battle по-разному регистрируются, то проще каждому сделать свою отдельную регистрацию Event/Competition/Registration и Event/Battle/Registration.

Ответить
Максим
2020-03-12 11:02

Да, регистрации разные. Кроме того, есть система подсчета результатов для каждого события.

В итоге получается:
Event/Competition/Registration
Event/Competition/Result

Event/Battle/Registration
Event/Battle/Result

Вот и подумал, может это вынести в отдельные системы, как вы говорили про склад и другие...

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий