core: Releases 2.4.3+ break support for using the default messenger serializer with the Messenger component
Scenario
According to this documentation, one can use the messenger component to implement the CQRS pattern. Such classes don’t have an IRI. Starting with Symfony 4.3, the default serializer was changed, but it can be reverted like so:
framework:
messenger:
serializer:
default_serializer: messenger.transport.symfony_serializer
symfony_serializer:
format: json
context: { }
transports:
async_priority_normal:
dsn: # ...
serializer: messenger.transport.symfony_serializer
When doing this, the AbstractItemNormalizer is used for message serialization like when using Symfony 4.2 on Api-Platform 4.2. The problem arises due to changes on commit 2bb4db1583521be72144d1da7da9cbe0b09808a2.
Expected Behavior
When using Symfony 4.2 with Api-Platform 2.4.2 using the above serializer, the expected behavior of implementing the CQRS pattern is that it should work as intended.
Actual Behavior
When using Symfony 4.3 with any release after 2.4.2, the above fails when using the messenger.transport.symfony_serializer service for serialization.
The reason is that the normalizer expects to be able to obtain an IRI from the object. This will not work because Commands can’t have an IRI. The guilty segment is this one:
$iri = $context['iri'] ?? $this->iriConverter->getIriFromItem($object);
The above was previously guarded by the following if and inside it:
if (isset($context['resources'])) {
$context['resources'][$iri] = $iri;
}
How to reproduce
Implement the example in https://api-platform.com/docs/core/messenger/ and make changes inside the file messenger.yaml to match the following:
framework:
messenger:
serializer:
default_serializer: messenger.transport.symfony_serializer
symfony_serializer:
format: json
context: { }
# ...
Doing the above will result in the following error:
No item route associated with the type "App\Entity\ResetPasswordRequest".
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 30 (15 by maintainers)
@teohhanhui
CQRS requires the implementation of, at least, one feature inside Api-Platform itself, like the
messengerattribute in the resource annotation. The docs show an example of how to do this. Is that doc entry still showing a supported feature or not?To be more specific, is the messenger attribute still a supported feature of the resource annotation? Is the example in the documentation a valid, supported, way to implement anything inside Api-platform? I gather it’s not because it should have a get operation, but that is not why @soyuka closed the issue. So I’m trying to get some clarification.
I’m sorry to be so insistent but you haven’t been consistent if the official docs state in one example to implement CQRS that the
getis not required. As it stands, this particular official documentation contradicts what you’re stating right now.If the example stated in the docs is a mistake, that’s ok, but you should remove it then. I can make a PR to remove it if you want. But you have to realize that it’s not consistent if your docs point to two different stories. It’s bound to confuse someone else besides me.
I’m trying to not appear entitled because I understand this is voluntary work. I don’t demand that someone fix this, but this discussion still has to happen if the confusion is to be stopped.
Sorry, I can’t advise on CQRS as I’m not familiar enough with that. But a RESTful API is not made up of commands (verbs), but resources (nouns). The closest equivalent to what you’re looking for is already in our test suite (code I’ve shared above).
Interesting, tyvm about this input I’ll definitely try to prioritize this next week (will have some time to work on these issues).