8000 [WIP] Add getSupportedTypes method to Normalizers by Oipnet · Pull Request #5611 · api-platform/core · GitHub
[go: up one dir, main page]

Skip to content

[WIP] Add getSupportedTypes method to Normalizers #5611

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

Closed
wants to merge 5 commits into from

Conversation

Oipnet
Copy link
@Oipnet Oipnet commented Jun 2, 2023

Add getSupportedTypes method

Q A
Branch? main
Tickets #5610
License MIT

See the article https://symfony.com/blog/new-in-symfony-6-3-performance-improvements#improved-performance-of-serializer-normalizers-denormalizers

In Symfony 6.3, we've added a getSupportedTypes(?string $format): array method to normalizers/denormalizers so they can declare the type of objects that they can handle and whether they are cacheable.

Need help for others Normalizers

@Oipnet Oipnet changed the title [WIP] Update AbstractConstraintViolationListNormalizer.php [WIP] Add getSupportedTypes method to Normalizers Jun 2, 2023
@soyuka
Copy link
Member
soyuka commented Jun 2, 2023

If we're not using the $context in the support method it's quite easy to add in other normalizers, I'm on the symfony slack if you need more informations!

Copy link
@MaSpeng MaSpeng left a comment

Choose a reason for hiding this comment

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

Thanks for your initiative!

return true;
}

public function getSupportedTypes(?string $format)
{
return [
Copy link
Author

Choose a reason for hiding this comment

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

I'm really not sure about this modification.

I've tried to understand the purpose of the getSupportedTypes method and adapted it to our class.

I'm waiting for your feedback to continue on the subject.

Copy link

Choose a reason for hiding this comment

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

This method has the purpose to simplify and improve the build-up of the normalizer/denormalizer cache of the Symfony Serializer.

Symfony < 6.2 used the result of the supportsDenormalization and supportsNormalization to do this, but these methods could heavily rely on the actual data, type, context arguments which could cause significant performance impacts depending on the executed code.

You might wanna take a look at the Symfony blog post and the linked PR.

public function getSupportedTypes(?string $format)
{
return match($format) {
static::FORMAT => [
Copy link
Author

Choose a reason for hiding this comment

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

I'm really not sure about this modification.

I've tried to understand the purpose of the getSupportedTypes method and adapted it to our class.

I'm waiting for your feedback to continue on the subject.

Copy link
@MaSpeng < 8000 a class="author Link--primary text-bold css-overflow-wrap-anywhere " show_full_name="false" data-hovercard-type="user" data-hovercard-url="/users/MaSpeng/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/MaSpeng">MaSpeng Jun 7, 2023

Choose a reason for hiding this comment

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

Comment on lines +106 to +111
return [
HalItemNormalizer::class => true,
JsonApiItemNormalizer::class => true,
JsonLdItemNormalizer::class => true,
ItemNormalizer::class => true,
];
Copy link
@MaSpeng MaSpeng Jun 7, 2023

Choose a reason for hiding this comment

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

I think this must return ['object' => false].

The description of the getSupportedTypes method indicates a result cannot be cached when it depends on the context or on the data. which the AbstractItemNormalizer does.

Generally, this method should return which objects are supported by the normalizer, and these listed classes here are normalizers on their own which, will never be de/normalized by the ItemNormalizer.

Comment on lines +72 to +79
return match($format) {
static::FORMAT => [
HalCollectionNormalizer::class => true,
HydraCollectionNormalizer::class => true,
JsonApiCollectionNormalizer::class => true,
],
default => [],
};
Copy link

Choose a reason for hiding this comment

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

I think this must return ['*' => false].

The description of the getSupportedTypes method indicates a result cannot be cached when it depends on the context or on the data. which the AbstractCollectionNormalizer does, it verifies that the provided data is iterable.

@mrossard
Copy link
Contributor

I'm not sure you're going the right way about this - the supported types should be the ApiResources you want the normalizers to support, not nromalizer instances.

Depending on how symfony does this, it might be done when initializing operations - you'd register the classes you want supported on the right normalizer?

@john-dufrene-dev
Copy link

Someone have an exemple how to remove this depreciation ?

Thank in advance,

@MaSpeng
Copy link
MaSpeng commented Jun 13, 2023

@john-dufrene-dev this is the best example from the Symfony blog article. The documentation section about performance and custom normalizers is still describing the use of the deprecated methods.

This should be a good starting point to remove the deprecation in your own normalizers, for API Platform, at least the item normalizer seems to be a bit more complicated as it discovers the ability to support the provided data by evaluating if it's an API resource.

I think this normalizer has either no catchable supports method at the moment, based on this behavior, or another solution could be to discover all API resources in a compiler pass and pass this knowledge to the normalizer to look up, but I am not sure how this will behave if you add or remove an API Resource during development.

Also, this could still be a solution for a production environment where this will not change over time.

@john-dufrene-dev
Copy link

@MaSpeng

Okay thanks for your comment,

But in some project I don't use my own serialiser just default serializer but I have dépréciation.

Just need to wait New release with PR so if I understand ?

Sorry for m'y Bad english

@MaSpeng
Copy link
MaSpeng commented Jun 14, 2023

@john-dufrene-dev You are right, if you are facing indirect deprecations, from API Platform in this case, you have to wait for a release that fixes those.

@john-dufrene-dev
Copy link

@MaSpeng

Thanks for informations :)

@@ -54,11 +57,28 @@ public function supportsNormalization(mixed $data, string $format = null, array
return static::FORMAT === $format && is_iterable($data);
}

/**
* @deprecated since Symfony 6.3, use "getSupportedTypes(?string $format)" instead
Copy link
Contributor
@chalasr chalasr Jun 17, 2023

Choose a reason for hiding this comment

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

since API Platform ...

public function hasCacheableSupportsMethod(): bool
{
trigger_deprecation('symfony/serializer', '6.3', 'The "%s()" method is deprecated, use "getSupportedTypes()" instead.', __METHOD__);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
trigger_deprecation('symfony/serializer', '6.3', 'The "%s()" method is deprecated, use "getSupportedTypes()" instead.', __METHOD__);
trigger_deprecation('api-platform/core', '3.2', 'The "%s()" method is deprecated, use "getSupportedTypes()" instead.', __METHOD__);

Same for all notices (using the right package name) as this is API Platform's code

@chalasr
Copy link
Contributor
chalasr commented Jun 17, 2023

Since api-platform supports symfony/serializer 6.1 and higher, the CacheableSupportsMethodInterface methods must not be deprecated now as projects running API Platform with Symfony 6.1 wouldn't be able to adopt the new way given it doesn't exist there. We can only add the new method here and revisit when api-platform requires symfony 6.3+.

@mrossard
Copy link
Contributor

hey there @Oipnet , any news on that PR? Is it still ongoing?

@mrossard
Copy link
Contributor
mrossard commented Jul 15, 2023

I tried working a bit on a separate PR for this since there is no recent activity here.

It is still a draft since i haven't looked into testing this correctly, but it seems to do the job for my use...if you're interested i'd gladly take comments : #5672

@dunglas
Copy link
Member
dunglas commented Jul 24, 2023

Closed in favor of #5672. Thanks for having inited the work @Oipnet.

@dunglas dunglas closed this Jul 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0