diff --git a/components/messenger.rst b/components/messenger.rst index ce2ab655153..2700e3eec55 100644 --- a/components/messenger.rst +++ b/components/messenger.rst @@ -38,11 +38,33 @@ Concepts something can be a message broker or a third party API for example. **Receiver**: - Responsible for deserializing and forwarding messages to handler(s). This - can be a message queue puller or an API endpoint for example. + Responsible for retrieving, deserializing and forwarding messages to handler(s). + This can be a message queue puller or an API endpoint for example. **Handler**: Responsible for handling messages using the business logic applicable to the messages. + Handlers are called by the ``HandleMessageMiddleware`` middleware. + +**Middleware**: + Middleware can access the message and its wrapper (the envelope) while it is + dispatched through the bus. + Literally *"the software in the middle"*, those are not about core concerns + (business logic) of an application. Instead, they are cross cutting concerns + applicable throughout the application and affecting the entire message bus. + For instance: logging, validating a message, starting a transaction, ... + They are also responsible for calling the next middleware in the chain, + which means they can tweak the envelope, by adding items to it or even + replacing it, as well as interrupt the middleware chain. + +**Envelope** + Messenger specific concept, it gives full flexibility inside the message bus, + by wrapping the messages into it, allowing to add useful information inside + through *envelope items*. + +**Envelope Items** + Piece of information you need to attach to your message: serializer context + to use for transport, markers identifying a received message or any sort of + metadata your middleware or transport layer may use. Bus --- @@ -53,9 +75,9 @@ middleware stack. The component comes with a set of middleware that you can use. When using the message bus with Symfony's FrameworkBundle, the following middleware are configured for you: -#. ``LoggingMiddleware`` (logs the processing of your messages) -#. ``SendMessageMiddleware`` (enables asynchronous processing) -#. ``HandleMessageMiddleware`` (calls the registered handle) +#. :class:`Symfony\\Component\\Messenger\\Middleware\\LoggingMiddleware` (logs the processing of your messages) +#. :class:`Symfony\\Component\\Messenger\\Asynchronous\\Middleware\\SendMessageMiddleware` (enables asynchronous processing) +#. :class:`Symfony\\Component\\Messenger\\Middleware\\HandleMessageMiddleware` (calls the registered handler(s)) Example:: @@ -74,7 +96,7 @@ Example:: .. note:: - Every middleware needs to implement the ``MiddlewareInterface``. + Every middleware needs to implement the :class:`Symfony\\Component\\Messenger\\Middleware\\MiddlewareInterface`. Handlers -------- @@ -112,7 +134,7 @@ the ``SerializerConfiguration`` envelope:: ])) ); -At the moment, the Symfony Messenger has the following built-in envelopes: +At the moment, the Symfony Messenger has the following built-in envelope items: #. :class:`Symfony\\Component\\Messenger\\Transport\\Serialization\\SerializerConfiguration`, to configure the serialization groups used by the transport. @@ -151,6 +173,12 @@ The above example will forward the message to the next middleware with an additi envelope item *if* the message has just been received (i.e. has the `ReceivedMessage` item). You can create your own items by implementing :class:`Symfony\\Component\\Messenger\\EnvelopeAwareInterface`. +.. note:: + + Any envelope item must be php serializable if going through transport using + the :class:`Symfony\\Component\\Messenger\\Transport\\Serialization\\Serializer` + base serializer. + Transports ---------- @@ -160,7 +188,8 @@ transport will be responsible for communicating with your message broker or 3rd Your own Sender ~~~~~~~~~~~~~~~ -Using the ``SenderInterface``, you can create your own message sender. +Using the :class:`Symfony\\Component\\Messenger\\Transport\\SenderInterface`, +you can create your own message sender. Imagine that you already have an ``ImportantAction`` message going through the message bus and being handled by a handler. Now, you also want to send this message as an email. @@ -206,7 +235,7 @@ First, create your sender:: Your own Receiver ~~~~~~~~~~~~~~~~~ -A receiver is responsible for receiving messages from a source and dispatching +A receiver is responsible for getting messages from a source and dispatching them to the application. Imagine you already processed some "orders" in your application using a @@ -226,7 +255,7 @@ First, create your receiver:: use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Messenger\Envelope; - class NewOrdersFromCsvFile implements ReceiverInterface + class NewOrdersFromCsvFileReceiver implements ReceiverInterface { private $serializer; private $filePath; diff --git a/messenger.rst b/messenger.rst index 002acd02e5e..14f5f4d906e 100644 --- a/messenger.rst +++ b/messenger.rst @@ -84,7 +84,9 @@ message handler. It's a class with an ``__invoke`` method:: Message handlers must be registered as services and :doc:`tagged ` with the ``messenger.message_handler`` tag. If you're using the -:ref:`default services.yaml configuration `, +:ref:`default services.yaml configuration ` and implement +:class:`Symfony\\Component\\Messenger\\Handler\\MessageHandlerInterface` +or :class:`Symfony\\Component\\Messenger\\Handler\\MessageSubscriberInterface`, this is already done for you, thanks to :ref:`autoconfiguration `. If you're not using service autoconfiguration, then you need to add this config: @@ -543,11 +545,16 @@ for each bus looks like this: #. ``call_message_handler`` middleware. Will call the message handler(s) for the given message. -Adding your own Middleware -~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. note:: -As described in the component documentation, you can add your own middleware -within the buses to add some extra capabilities like this: + These middleware names are actually shortcuts working by convention. + The real service ids are prefixed with the ``messenger.middleware.`` namespace. + +Disabling default Middleware +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you don't want the default collection of middleware to be present on your bus, +you can disable them like this: .. configuration-block:: @@ -558,9 +565,7 @@ within the buses to add some extra capabilities like this: messenger: buses: messenger.bus.default: - middleware: - - 'App\Middleware\MyMiddleware' - - 'App\Middleware\AnotherMiddleware' + default_middleware: false .. code-block:: xml @@ -576,10 +581,7 @@ within the buses to add some extra capabilities like this: - - - - + @@ -591,23 +593,17 @@ within the buses to add some extra capabilities like this: 'messenger' => array( 'buses' => array( 'messenger.bus.default' => array( - 'middleware' => array( - 'App\Middleware\MyMiddleware', - 'App\Middleware\AnotherMiddleware', - ), + 'default_middleware' => false, ), ), ), )); -Note that if the service is abstract, a different instance of service will be -created per bus. - -Disabling default Middleware -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Adding your own Middleware +~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you don't want the default collection of middleware to be present on your bus, -you can disable them like this: +As described in the component documentation, you can add your own middleware +within the buses to add some extra capabilities like this: .. configuration-block:: @@ -618,7 +614,9 @@ you can disable them like this: messenger: buses: messenger.bus.default: - default_middleware: false + middleware: + - 'App\Middleware\MyMiddleware' + - 'App\Middleware\AnotherMiddleware' .. code-block:: xml @@ -634,7 +632,10 @@ you can disable them like this: - + + + + @@ -646,12 +647,18 @@ you can disable them like this: 'messenger' => array( 'buses' => array( 'messenger.bus.default' => array( - 'default_middleware' => false, + 'middleware' => array( + 'App\Middleware\MyMiddleware', + 'App\Middleware\AnotherMiddleware', + ), ), ), ), )); +Note that if the service is abstract, a different instance of the service will +be created per bus. + Using Middleware Factories ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -674,13 +681,13 @@ factories. Defining such requires a two-step configuration based on Symfony's # Step 2: an abstract definition that will call the factory with default # arguments or the ones provided in the middleware config - messenger.middleware.doctrine_transaction_middleware: + messenger.middleware.doctrine_transaction: class: Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware factory: 'doctrine.orm.messenger.middleware_factory.transaction:createMiddleware' abstract: true # the default arguments to use when none provided from config. Example: # middleware: - # - doctrine_transaction_middleware: ~ + # - doctrine_transaction: ~ arguments: ['default'] .. code-block:: xml @@ -703,7 +710,7 @@ factories. Defining such requires a two-step configuration based on Symfony's - @@ -729,7 +736,7 @@ factories. Defining such requires a two-step configuration based on Symfony's // Step 2: an abstract definition that will call the factory with default // arguments or the ones provided in the middleware config - $container->register('messenger.middleware.doctrine_transaction_middleware', DoctrineTransactionMiddleware::class) + $container->register('messenger.middleware.doctrine_transaction', DoctrineTransactionMiddleware::class) ->setFactory(array( new Reference('doctrine.orm.messenger.middleware_factory.transaction'), 'createMiddleware' @@ -742,7 +749,7 @@ which is the argument expected by the ``Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddlewareFactory::createMiddleware`` method. Then you can reference and configure the -``messenger.middleware.doctrine_transaction_middleware`` service as a middleware: +``messenger.middleware.doctrine_transaction`` service as a middleware: .. configuration-block:: @@ -755,9 +762,9 @@ Then you can reference and configure the command_bus: middleware: # Using defaults - - doctrine_transaction_middleware + - doctrine_transaction # Using another entity manager - - doctrine_transaction_middleware: ['custom'] + - doctrine_transaction: ['custom'] .. code-block:: xml @@ -775,9 +782,9 @@ Then you can reference and configure the - + - + custom @@ -794,20 +801,15 @@ Then you can reference and configure the 'command_bus' => array( 'middleware' => array( // Using defaults - 'doctrine_transaction_middleware', + 'doctrine_transaction', // Using another entity manager - array('id' => 'doctrine_transaction_middleware', 'arguments' => array('custom')), + array('id' => 'doctrine_transaction', 'arguments' => array('custom')), ), ), ), ), )); -.. note:: - - The ``doctrine_transaction_middleware`` shortcut is a convention. The real - service id is prefixed with the ``messenger.middleware.`` namespace. - .. note:: Middleware factories only allow scalar and array arguments in config (no @@ -816,9 +818,9 @@ Then you can reference and configure the .. tip:: - The ``doctrine_transaction_middleware`` is a built-in middleware wired - automatically when the DoctrineBundle and the Messenger component are - installed and enabled. + The ``messenger.middleware.doctrine_transaction`` middleware is a built-in + middleware wired automatically when the DoctrineBundle and the Messenger + component are installed and enabled. Your own Transport ------------------