-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Messenger] deserialize third-party messages into a generic class for consumption #31230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hey @dvc! What you need for this is a custom transport serializer. Without the But, two more things:
|
Hello @weaverryan ! Thanks for comment. I don't think about custom serializer. I can configure custom transport (for transport level customization ) to use custom Receiver logic (https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Messenger/Transport/AmqpExt/AmqpReceiver.php#L66). But! It is interesting idea to support default deserialization type by Serializer configuration (concrete class, some generic object with array payload inside or just stdClass/array). Imho, it could be useful for some use cases. And after that allow to set/override this default in some messenger config. For example:
|
We can see if other people are also interested in something like this. It can already be accomplished currently (as we discussed), so it's a question of: is this common enough that we should make it easier to accomplish :). Cheers! |
Agree. Request for comments... |
Indeed, creating your own serializer (decorating the default one for simplicity) is the best thing to do IMHO. Did you manage to do this? If so, can you share your piece of code so that others can get inspired? |
Hello @sroze! In 4.2 default serializer has public static constructor: https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/Messenger/Transport/AmqpExt/AmqpReceiver.php#L35 So, i have to extend Symfony\Component\Messenger\Transport\Serialization\Serializer and override decode-method with some logic to set default type. Something like this:
But this configuration affects also amqp.out transport and all amqp. Because of using Transport factory. I have no information in transport factory to customize concrete transport with defaults for receive type. |
In my use case default type is about custom transport/exchange/queue. I believe in remote configuration for this message source. Only one type in this channel. For most common defaults: IMHO, both of this cases is not about serializers, but about transports. |
Configuring a
So configuring a custom serializer is the only option, esp. if you want to deserialize into a custom type. What could be useful in core is a serializer that more easily allows to consume third party messages without having to create a custom serializer. It could simply create a fixed GenericMessage object that gives access to the raw body and headers. This way, you can consume those messages and wire your handlers using the GenericMessage class. |
@Tobion, lets separate use cases:
Lets say about ability to adding any custom headers by transport for any needs. RequestId, sourceId, message encoding, translate key,.. anything. Some of this requires functions support. Hooks/events or middlewares. This headers should be added to envelop, imho. BTW, i'm not sure about php serializer. I think it should works well because of zero config on serializer level. And. Invalid message content (invalid default or custom type header) - is real use case. It requires custom ExceptionEvent (with envelop). |
I agree with those use-cases. For 1) I proposed a solution. For 2) I think a custom serializer is the correct solution. The question is only if we need to make it even easier to create custom serializers with different classes to deserialize into, so you could configure transport x to deserialize all messages to class y. |
Well, i am not insist on my variant. Convenient serializer configuration is good solution. |
Now (in 4.3) you can configure the Serializer service per transport. So you can easily have your only for one transport. If think that this closes the issue, I agree with @Tobion on the other points :) |
This issue is getting referenced time to time on Slack. I would like to share my custom built serializer just for this purpose: https://github.com/Happyr/message-serializer It basically does a json_encode but also forces you do add a message type/id and a version. |
Hello everybody!
Description
I want to receive and handle messages from 3rd party publishers without required headers.
May be some "global" fallback, and/or default type for every transport.
Can i?
Example
Simple message with payload and without ['headers']['type'] throws error:
'Encoded envelope does not have a "type" header.'
The text was updated successfully, but these errors were encountered: