-
-
Notifications
You must be signed in to change notification settings - Fork 897
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
feat(symfony): Autoconfigure classes using #[ApiResource]
attribute
#6943
base: 4.1
Are you sure you want to change the base?
Conversation
src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
Outdated
Show resolved
Hide resolved
24c6b04
to
939fe53
Compare
src/Symfony/Bundle/DependencyInjection/Compiler/AttributeResourcePass.php
Outdated
Show resolved
Hide resolved
#[ApiResource]
attribute#[ApiResource]
attribute
#[ApiResource]
attribute#[ApiResource]
attribute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very smart! I like this.
Nice! It reminds me a discussion we had with @nicolas-grekas ^^. core/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php Lines 342 to 348 in 7b3bf83
The way core/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php Lines 385 to 433 in 7b3bf83
This is quite heavy work for no real gain, especially that the resources discovered with this patch will already be discovered there right? Last thing, inside the route loader we declare directory resources (so that the container is rebuilt when these file changes) at: core/src/Symfony/Routing/ApiLoader.php Lines 52 to 54 in 7b3bf83
If we remove that |
Removing the directory scanning would be a breaking change as the Of-course, this is the target. |
Mhh okay but this means that we only need this for the Entity directory, we can remove all the code handling our paths (for example ApiResource). What about the DirectoryResource to rebuild the container on file change? Are services tagged as |
If this doesn’t work for the Entity directory (that we won’t deprecate IMHO), then is this patch really useful? |
Let's reintroduce the I'll try to move the directory scan to the compiler pass. |
32ba921
to
d2a7a55
Compare
Well, I haven't found a solution yet to avoid scanning the configured folders twice (all the Entity, Document and ApiResource folders of the project and bundles).
|
…)` and `ContainerBuilder::findExcludedServiceIds()` for auto-discovering value-objects (GromNaN) This PR was squashed before being merged into the 7.3 branch. Discussion ---------- [DependencyInjection] Add `Definition::addExcludedTag()` and `ContainerBuilder::findExcludedServiceIds()` for auto-discovering value-objects | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | - | License | MIT We could **not** use the method `findTaggedServiceIds` in #59401 (comment), same for api-platform/core#6943. As "using the container loading tools to do resource discovery quite seamlessly" [seems to be a good idea](#59401 (review)), this changes make it easier. I'm not closed to alternative ideas if we want to go further with this use-case. ### Usage Let's create a `AppModel` attribute class and use it on any class of the project. In the extension class: ```php $this->registerAttributeForAutoconfiguration(AppModel::class, static function (ChildDefinition $definition) { $definition->addExcludedTag('app.model'); }); ``` In a compiler pass: ```php $classes = []; foreach($containerBuilder->findExcludedServiceIds('app.model') as $id => $tags) { $classes[] = $containerBuilder->getDefinition($id)->getClass(); } $containerBuilder->setParameter('.app.model_classes', $classes); ``` And this parameter can be injected into a service, or directly update a service definition to inject this list of classes. The attribute parameters can be injected into the tag, and retrieved in the compiler pass, for more advanced configuration. Commits ------- 7a0443b [DependencyInjection] Add `Definition::addExcludedTag()` and `ContainerBuilder::findExcludedServiceIds()` for auto-discovering value-objects
So I think we need to move the extraction of the classes names into the compiler pass and inject them into a |
Here's how it should be designed to take full advantage of the container builder. Goals
Advantage: no need for additional cache unless explicitly required by a custom implementation Backward-compatibility constraints:
AttributesDetection: Use Symfony Cache invalidation: The Symfony cache is automatically invalidated and regenerated when one of this classes is modified, removed or added in the autoconfigured directories. XML/Yaml filesDetection:: List files during container compilation. Cache invalidation: Adding this files and directories as "resources"; even if they doesn't exist, the container cache is automatically invalidated and regenerated when on of the files is modified, removed or added in the configured directories. |
Using the Symfony bundle, classes with the
#[ApiResource]
attribute must be insrc/ApiResource
,src/Entity
(for Doctrine ORM) orsrc/Document
(for MongoDB ODM). It's possible to add custom paths in the configuration, but that's one more little thing to take care of.By using the Symfony autoconfiguration feature, we can detect classes with the
#[ApiResource]
attribute during the build of the container instead of scanning directories at runtime.The same feature was implemented in Symfony for the
#[JsonEncodable]
attribute: symfony/symfony#59401