Декілька автобусів

Дата оновлення перекладу 2022-11-22

Декілька автобусів

Розповсюдженою архітектурою при створенні додатків є розділення команд і запитів. Команди - це дії, які щось роблять, а запити - вилучають дані. Це називається CQRS (Розділення призначень запитів і команд). Прочитайте статтю про CQRS Мартіна Фоулера, щоб дізнатися більше. Ця архітектура може бути використана сумісно з компонентом Messenger, шляхом визначення декількох автобусів.

Автобус команд трохи відрізняється від автобуса запитів. Наприклад, автобуси команд зазвичай не надають ніяких результатів, а автобуси запитів рідко бувають асинхронними. Ви можете сконфігурувати ці автобуси та їх правила, використовуючи проміжкове ПЗ.

Ще може бути гарною ідеєю розділяти дії та реакції, шляхом введення автобуса подій. Автобус подій може мати 0 або більше підписників.

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
framework:
    messenger:
        # Автобус, який буде впроваджено при впровадженні MessageBusInterface
        default_bus: command.bus
        buses:
            command.bus:
                middleware:
                    - validation
                    - doctrine_transaction
            query.bus:
                middleware:
                    - validation
            event.bus:
                default_middleware:
                    enabled: true
                    # встановіть "allow_no_handlers" як true (за замовчуванням - false), щоб дозволити
                    # відсутніть сконфігурованого обробника для цього автобуса, але без виклику виключення
                    allow_no_handlers: false
                    # встановіть "allow_no_senders" (за замовчуванням - true), щоб викликати виключення,
                    # якщо для цього автобуса не сконфігуровано відправника
                    allow_no_senders: true
                middleware:
                    - validation

6.2

Опція allow_no_senders була представлена в Symfony 6.2.

Це створить три нових сервіси:

  • command.bus: автомонтований з підказкою MessageBusInterface (так як це default_bus);
  • query.bus: автомонтований за допомогою MessageBusInterface $queryBus;
  • event.bus: автомонтований за допомогою MessageBusInterface $eventBus.

Обмеження обробників за автобусами

За замовчуванням, кожний обробник буде доступний для обробки повідомлень у всіх ваших автобусах. Щоб запобігти запуску повідомлення у неправильний автобус без помилки, ви можете обмежити кожного обробника за конкретним автобусом, використовуючи тег messenger.message_handler:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
# config/services.yaml
services:
    App\MessageHandler\SomeCommandHandler:
        tags: [{ name: messenger.message_handler, bus: command.bus }]
        # запобігає подвійній реєстрації обробників (або ви можете видалити
        # MessageHandlerInterface, який автоконфігуратор використовує для виявлення обробників)
        autoconfigure: false

Таким чином, обробник App\MessageHandler\SomeCommandHandler буде відомий лише автобуса command.bus.

Ви також можете автоматично додати цей тег до визначеної кількості класів, використовуючи _екземпляр конфігурації сервісу. Використовуючи це, ви зможете визначити автобус повідомлень, засновуючись на реалізованому інтерфейсі:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# config/services.yaml
services:
    # ...

    _instanceof:
        # всі сервіси, що реалізують CommandHandlerInterface,
        # будуть зареєстровані в автобусі command.bus
        App\MessageHandler\CommandHandlerInterface:
            tags:
                - { name: messenger.message_handler, bus: command.bus }

        # в той час як ті, що реалізують QueryHandlerInterface, будуть
        # зареєстровані в автобусі query.bus
        App\MessageHandler\QueryHandlerInterface:
            tags:
                - { name: messenger.message_handler, bus: query.bus }

Налагодження автобусів

Команда debug:messenger перераховує доступні повідомлення та обробники для кожного автобуса. Ви також можете обмежити список за певним автобусом, надавши його назву в якості аргументу.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ php bin/console debug:messenger

  Messenger
  =========

  command.bus
  -----------

   Наступні повідомлення можуть бути запущені:

   ---------------------------------------------------------------------------------------
    App\Message\DummyCommand
        handled by App\MessageHandler\DummyCommandHandler
    App\Message\MultipleBusesMessage
        handled by App\MessageHandler\MultipleBusesMessageHandler
   ---------------------------------------------------------------------------------------

  query.bus
  ---------

   Наступні повідомлення можуть бути запущені:

   ---------------------------------------------------------------------------------------
    App\Message\DummyQuery
        handled by App\MessageHandler\DummyQueryHandler
    App\Message\MultipleBusesMessage
        handled by App\MessageHandler\MultipleBusesMessageHandler
   ---------------------------------------------------------------------------------------

Tip

Починаючи з Symfony 5.1, команда також відображатиме опис повідомлення PHPDoc та класи обробника.