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)

Most upvoted comments

@teohhanhui

CQRS requires the implementation of, at least, one feature inside Api-Platform itself, like the messenger attribute 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 get is 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).