You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There are a variety of existing message brokers, and don't know all of them, I have to admit that my knowledge is still young and limited on this topic, but it seems that in theory in most of them, a message is anything but a simple byte stream.
In a way, I do understand (if my assumptions are correct) why the choice of always typing messages using a valid PHP class so you can type and route them to their handlers very easily. But in way, it looses flexibility and prevent interoperability in heterogeneous existing environments:
you can't just receive messages that have names such as order.prepare for example, which in the end could actually quite happen with some message brokers, if I read correctly AMQP spec for example, there's an arbitrary yet in the protocol message property which is called type (I might be wrong on this one, spec is not an easy beast to read),
you can't send them either, or you will need to write a custom middleware, but it would be sad to let end user do this on every project they need it,
you could receive messages which are bare strings, no content-type, no serialization,
you can't send them either (a.k.a. "Hello, World!" for example).
As soon as you enter an existing environment based upon a message broker that as any of those specificity, you cannot use the Symfony messenger within.
This is a feature request, but also a support question at the same time, is it going to be supported ?
I could see many ways to allow this:
allow messages to be bare strings but wrap them in a default StringMessage or ArbitraryMessage class with tow methods getValue(): string or getContents(): string and getType(): string method when receiving them,
ask for the developer to wrap the message by itself in that very same class when sending them,
plug a type to class map middleware that would convert order.prepare to App\Domain\Order\Event\OrderPrepareMessage back and forth, this map would need to be configurable at the project level by either a raw YAML configuration in the config/ folder or using annotations on the messages classes, such as @Message(type="order.prepare") for example, or any other easy to use way of letting the application developper defining it (personally I don't love annotations, and in the projects I work on, we don't use them at all),
give a way for the end-user developer to pass the arbitrary type (for when it's a not a class but a bare string message) to the dispatch() method, either by an additional parameter or using something like a MessageTypeStamp or directly setting a type property on the StringMessage class,
message type is not a universally thing amongst message brokers, but let those that don't support it fail when sending or ignore when receiving, the application developer must be in control of these aspects, not the messenger component itself.
That's my 2 cents, I have no extensive knowledge about message brokers and message buses, but it seems rather sane to consider that messages are nothing more than bare byte streams when they're dispatched, and not all messages will end up being nice hydratable JSON or XML.
For example, it seems totally fine, IMHO to send such message within a bus and expect a business consuming application to be able to process it:
Headers/Properties/Attributes (name it using your message broker own semantics):
content-type: application/octet-stream
type: product.delete
Content:
12
Where 12 is an identifier, but as a message broker, I don't care what it is, it is the consumer responsibility to know what to do about that, and maybe messenger should not be that strict upon internal routing within the application, some handler could just receive untyped messages and process them with instanceof statements.
May be an additional handler interface could also carry a handle($message, string $type) method ?
The text was updated successfully, but these errors were encountered:
pounard
changed the title
[Messenger] Message can be bare strings or empty, message type cannot be an arbitrary string
[Messenger] Message cannot be bare strings or empty, message type cannot be an arbitrary string
Aug 28, 2019
I don't think having a custom serializer does solve everything. Having a default fallback mechanism that just would propagate the raw string into a default class could be a nice thing to have in this component. It still would fail if there's no handler to deal with it, but it'd leave the opportunity for handlers to target this class and do whatever they want to with, without needing to override the serializer at the project level.
Uh oh!
There was an error while loading. Please reload this page.
There are a variety of existing message brokers, and don't know all of them, I have to admit that my knowledge is still young and limited on this topic, but it seems that in theory in most of them, a message is anything but a simple byte stream.
In a way, I do understand (if my assumptions are correct) why the choice of always typing messages using a valid PHP class so you can type and route them to their handlers very easily. But in way, it looses flexibility and prevent interoperability in heterogeneous existing environments:
you can't just receive messages that have names such as
order.prepare
for example, which in the end could actually quite happen with some message brokers, if I read correctly AMQP spec for example, there's an arbitrary yet in the protocol message property which is calledtype
(I might be wrong on this one, spec is not an easy beast to read),you can't send them either, or you will need to write a custom middleware, but it would be sad to let end user do this on every project they need it,
you could receive messages which are bare strings, no content-type, no serialization,
you can't send them either (a.k.a. "Hello, World!" for example).
As soon as you enter an existing environment based upon a message broker that as any of those specificity, you cannot use the Symfony messenger within.
This is a feature request, but also a support question at the same time, is it going to be supported ?
I could see many ways to allow this:
StringMessage
orArbitraryMessage
class with tow methodsgetValue(): string
orgetContents(): string
andgetType(): string
method when receiving them,order.prepare
toApp\Domain\Order\Event\OrderPrepareMessage
back and forth, this map would need to be configurable at the project level by either a raw YAML configuration in theconfig/
folder or using annotations on the messages classes, such as@Message(type="order.prepare")
for example, or any other easy to use way of letting the application developper defining it (personally I don't love annotations, and in the projects I work on, we don't use them at all),dispatch()
method, either by an additional parameter or using something like aMessageTypeStamp
or directly setting atype
property on theStringMessage
class,That's my 2 cents, I have no extensive knowledge about message brokers and message buses, but it seems rather sane to consider that messages are nothing more than bare byte streams when they're dispatched, and not all messages will end up being nice hydratable JSON or XML.
For example, it seems totally fine, IMHO to send such message within a bus and expect a business consuming application to be able to process it:
Where 12 is an identifier, but as a message broker, I don't care what it is, it is the consumer responsibility to know what to do about that, and maybe messenger should not be that strict upon internal routing within the application, some handler could just receive untyped messages and process them with
instanceof
statements.May be an additional handler interface could also carry a
handle($message, string $type)
method ?The text was updated successfully, but these errors were encountered: