Skip to content
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

fix: use name_converter in Doctrine LinksHandler if defined #5754

Open
wants to merge 2 commits into
base: 3.1
Choose a base branch
from

Conversation

pdesgarets
Copy link

Q A
Branch? 3.1
Tickets Closes #5723
License MIT

Use api_platform.name_converter service in LinksHandlerTrait to match the correct link.

Needs tests but I don't really understand the testing policy, I could use some help.

@pdesgarets pdesgarets changed the base branch from main to 3.1 August 17, 2023 13:51
@pdesgarets
Copy link
Author

It's a nightmare having to define operations / links etc to make a unit test covering these lines. I will see if I can create an integration test instead.

@@ -41,7 +43,8 @@ private function getLinks(string $resourceClass, Operation $operation, array $co
$linkProperty = $context['linkProperty'] ?? null;

foreach ($links as $link) {
if ($linkClass === $link->getFromClass() && $linkProperty === $link->getFromProperty()) {
$testedProperty = $this->nameConverter ? $this->nameConverter->normalize($link->getFromProperty()) : $link->getFromProperty();
if ($linkClass === $link->getFromClass() && $linkProperty === $testedProperty) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I understand, what's your resource configuration? why isn't the fromProperty already the correct name? this should happend way before reaching this code, for example in a MetadataFactory, although I don't get the use case, just configure the property manually?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My resource configuration is minimalist, #[ApiResource]. The fromProperty is set during the cache:clear, using the default LinkFactory that reads the relations. If the link fromProperty is set to the serialized form, the mapping can not be recovered in the getAssociationMapping call (https://github.com/api-platform/core/blob/main/src/Doctrine/Orm/State/LinksHandlerTrait.php#L80).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note : my test setting fromProperty to the serialized form in the LinkFactory was made using a code like

            $fromProperty = $this->nameConverter ? $this->nameConverter->normalize($property) : $property;
            $link  = $link->withFromProperty($fromProperty);

and the fromProperty can not be manually set using a Link attribute, because the $attributeLink coming from the reflection is not used at all (https://github.com/api-platform/core/blob/main/src/Metadata/Resource/Factory/LinkFactory.php#L103C26-L103C72) (?!)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to put the name converter inside https://github.com/api-platform/core/blob/main/src/Metadata/Resource/Factory/LinkResourceMetadataCollectionFactory.php#L44 instead ? (or in the link factory) like this it'd be cached

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LinkFactory must not set the fromProperty to the normalized form because it would break the getAssociationMapping call (https://github.com/api-platform/core/blob/main/src/Doctrine/Orm/State/LinksHandlerTrait.php#L80).

The only alternative I see (if we want to use the cache) would be to add another property to the Link, having both fromProperty and (e.g.) fromPropertyNormalized, both set in the Link Factory. But it looks like a quite heavy change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a hard time understanding the whole logic behind this there's something wrong... links should only handle property mapping, in the code nothing looks like bar_converted so this needs to be before we reach that part of the code. It's the request body itself that should be transformed to give barConverted at that point.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Yes I guess we can do the other way around, and use $this->nameConverter->denormalize($info->fieldName) when $context['linkProperty'] is set in https://github.com/api-platform/core/blob/3.1/src/GraphQl/Resolver/Stage/ReadStage.php#L86-L86

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mhh probably can you give me a bit more time? I need to take a deeper look into that but I won't be able to until oct/nov...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I am using API Platform in prod with this exact use case and I see no workaround so I will use my fork in the meantime

@pdesgarets pdesgarets force-pushed the use-name-converter branch 2 times, most recently from dec5cd3 to 6ad70a8 Compare August 18, 2023 15:25
@pdesgarets
Copy link
Author

I added a Behat test in 6ad70a8

This commit can be cherry picked on branch 3.1 if you want to see the test failing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to use GraphQL to retrieve linked entities with a non-default name_converter
2 participants