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

Allow multiple AsDecorator attributes on a decorating class #50228

Closed
tjveldhuizen opened this issue May 3, 2023 · 4 comments
Closed

Allow multiple AsDecorator attributes on a decorating class #50228

tjveldhuizen opened this issue May 3, 2023 · 4 comments

Comments

@tjveldhuizen
Copy link
Contributor

Description

I have a situation in API Platform, in which I want to decorate the api_platform.jsonld.normalizer.item and api_platform.hal.normalizer.item with the same decorator. In short, that decorator adds a property to the normalized item.

In #45834, in addition to the configuration of a decorator in the service definition, it's made possible to do this using a PHP attribute #[AsDecorator]. Unfortunately, it's not possible to repeat this attribute.

I've done a quick test making the attribute repeatable, but this results in the decorator applied to the first service being overwritten by the second one, I think because of the same reason as described here: the name of the decorating service is reused. Therefore, this feature requires more work than just making the attribute repeatable: generating (or demanding configuration) unique service names is required.

Example

<?php

namespace App\ApiPlatform\Normalizer;

use App\ApiPlatform\Attribute\HateoasLink;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;

#[AsDecorator('api_platform.jsonld.normalizer.item')]
#[AsDecorator('api_platform.hal.normalizer.item')]
class HateoasLinkNormalizer implements NormalizerInterface, SerializerAwareInterface
{
    public function __construct(
        private readonly NormalizerInterface $decorated,
        private readonly RouterInterface $router,
    ) {
    }

    // ...
}
@stof
Copy link
Member

stof commented May 3, 2023

A single service cannot decorate multiple other services. That's why the attribute cannot be repeated.

@stof
Copy link
Member

stof commented May 3, 2023

Autoconfiguration features are about configuring the registered service, not creating new ones by duplicating it under a different id. So we cannot automatically register cloned definitions of the service to decorate multiple services (and trying to do that might cause issues in other layers, by registering those alternative definitions much later in the processing)

@tjveldhuizen
Copy link
Contributor Author

A single service can not, but a single class can be used to instantiate multiple decorating services, isn't it? It looks like that is the way it works when I follow the API Platform documentation.

@nicolas-grekas
Copy link
Member

Sure, but the attribute is about registering the service.
It looks like you need to register your class twice.
Closing as explained by @stof

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

No branches or pull requests

3 participants