Skip to content

[Serializer] Custom normalizer example is recursive #19068

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
jennevdmeer opened this issue Oct 20, 2023 · 6 comments
Closed

[Serializer] Custom normalizer example is recursive #19068

jennevdmeer opened this issue Oct 20, 2023 · 6 comments

Comments

@jennevdmeer
Copy link
Contributor

jennevdmeer commented Oct 20, 2023

The 7.0 example for the custom normalizer (https://symfony.com/doc/7.0/serializer/custom_normalizer.html) is a recursive example and could use more details.

class TopicNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
use NormalizerAwareTrait;
public function __construct(
private UrlGeneratorInterface $router,
) {
}
public function normalize($topic, string $format = null, array $context = []): array
{
$data = $this->normalizer->normalize($topic, $format, $context);

Using NormalizerAwareInterface and NormalizerAwareTrait will inject the full instance of the Serializer class (
https://github.com/symfony/symfony/blob/d741f387eedb2a25cd513cb6472e3456baa5fe4e/src/Symfony/Component/Serializer/Serializer.php#L92-L94).

The $this->normalizer->normalize(... call (line 40 above) would then just call the normalize on the same serializer and end up in the same normalizer recursively.

After a discussion in slack with @Pixelshaped having questions with the public function getSupportedTypes(?string $format): array; and Stof joining in we came to a few conclusions;

  • Stof mentioned: The basic example of a custom normalizer should use a different use case that this re-entrant normalization that require avoiding infinite loops, I though maybe a custom normalizer for a Money type (amount/currency) could work as an example but any recommendations are appreciated.
  • As from @Pixelshaped initial questions the Performance of Normalizers/Denormalizers section could use a better description/example as to when a normalizer can or can not be cached (I've seen this question a few times in slack, it seems not really clear from the docs).
    Most confusion is that people think it would cache the normalization result. While in fact it just caches if the normalizer class should be reused directly from the hashmap, without checking supportsNormalization if data is of said specific type(s).
  • One thing I found missing was does inheritance work when defining getSupportedTypes types. Afaik this is false(?) as it creates a hashmap for lookup, but might be worth mentioning.

To help with the getSupportedTypes the current example could be used with a proper workaround like described at API platform or SymfonyCasts by using some kind of marker in the context. Or if anyone knows a different (easier) use case to clearly show the difference between CAN and CAN NOT be cached please!

Which effectively makes the normalize not cacheable as supportsNormalization needs to be handled on an object by object case.

And finally since 6.3 docs there is a info block saying "Injecting ObjectNormalizer is deprecated, however the example above it does not show how to properly do it. I don't know if its common to have it like this but I would think having a proper example (same as mentioned above?) there would be useful to get rid of the deprecation.

@carsonbot
Copy link
Collaborator

Thank you for this issue.
There has not been a lot of activity here for a while. Has this been resolved?

@jennevdmeer
Copy link
Contributor Author

No

@carsonbot carsonbot removed the Stalled label Oct 22, 2024
@xabbuh
Copy link
Member

xabbuh commented Oct 22, 2024

Are you sure that the changes from #19532 did not resolve this?

@jennevdmeer
Copy link
Contributor Author

It did, well the recursive part. It does inject the object normalizer instead of the serializer now, sorry didn't really look.

However I still think the getSupportedTypes could use some dumbing down/detailing. How do we proceed? New issue/edit title&post?

@xabbuh
Copy link
Member

xabbuh commented Oct 22, 2024

yeah, I think a new issue is the best way forward

@jennevdmeer
Copy link
Contributor Author

Continued in #20341 then, thanks :)

@jennevdmeer jennevdmeer closed this as not planned Won't fix, can't repro, duplicate, stale Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants