Uh oh!
There was an error while loading. Please reload this page.
feat(doctrine): stateOptions can handleLinks for query optimization - #5732
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
57b5273 to
e13f29dComparemrossard
commented
Aug 9, 2023
I love the idea! |
Uh oh!
There was an error while loading. Please reload this page.
divine
commented
Aug 10, 2023
Hello, I truly appreciate your work, @soyuka. Thank you very much. Everything looks nearly perfect, and I've removed 2 files that I've copied from the APP (CollectionProvider and ItemProvider). I've tested it locally now, but I'm facing a problem while trying to inject the Is there a way to inject it or make it that work? Thanks! |
soyuka
commented
Aug 10, 2023
I need to add a way to call services for that to work! |
usu
commented
Aug 14, 2023
Tested with my problem described in #5673 and worked well for me. Thanks a lot! Minor thing: In your example above in the PR description, I think you'd still need to include the #[ApiResource(
uriTemplate: '/company/{company}/employees/{employee}',
uriVariables: ['company', 'employee'],
stateOptions: newOptions(handleLinks: [Employee::class, 'handleLinks'])
)]Not really relevant for this PR itself, but probably relevant for the documentation of this new feature. |
dunglas
commented
Aug 15, 2023
Your proposal looks great! Regarding services, we should do as for similar options, controllers etc and call the service with that name of it exists. |
divine
commented
Sep 2, 2023
Hello, Sorry to bump. Can this feature be included in the 3.2 release cycle? Otherwise, I'm worried this will be forgotten. Thank you so much @soyuka! |
soyuka
commented
Sep 2, 2023
I'm curently adding a service locator to improve this a bit |
ca5bcea to
aef6e86CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| { | ||
| $resourceClass = $operation->getClass(); | ||
| $documentClass = $operation->getClass(); | ||
| if (($options = $operation->getStateOptions()) && $options instanceof Options && $options->getDocumentClass()) { |
There was a problem hiding this comment.
Redundant with DoctrineMongoDbOdmResourceCollectionMetadataFactory, ODM/ItemProvider, ODM/LinksHandlerTrait, GraphQl/FieldsBuilder, Hydra/CollectionFiltersNormalizer, etc.
Can't it be in a more generic trait (e.g. Doctrine/Common/OptionsTrait) or something similar? (same with ORM)
There was a problem hiding this comment.
This is a quite hard problem I'm not a huge fan of the current dependency between CollectionFiltersNormalizer and state options as when we'll need to subtree split we potentially won't have access to them. When working on this we probably need to uplift this information into some $context['filter_class'] as this option allows filters do be described on an entity instead of on a resource... This adds complexity whereas to where to put the Trait, and also would need specific implementations (ODM vs ORM). I'd like to keep this as-is for now.
Magic is hard to implement correctly :|.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
a7dd210 to
927ab07CompareUh oh!
There was an error while loading. Please reload this page.
927ab07 to
c33fa22Comparec33fa22 to
111a066Compare
First, this patch allows
stateOptions: entityClassto work with Doctrine ODM (I'll move this to another patch though).Then, it provides a way to hook into our providers to change how links are provided to Doctrine. This really help with improving performances, it is quite complicated let me try to explain.
The Problem
Say you have
/company/les-tilleuls/employees/soyuka. API Platform tries to handle your links, and the algorithm tries to cover all the cases so it'd probably do something like this:First it's not that simple as we work with doctrine, relations between multiple tables and different nature (toMany, toOne) are sometimes really tricky and API Platform does things like this:
Depending on the nature of the relation it can be over-complicated and probably also bad in term of query performances.
A solution to this is to say that, depending on business rules, we decide to use:
DX
Today you'd have to write a custom provider. Thing is, people love our filters and our pagination handling. Despite trying my best to work on that extensibility, for now, the best is to "copy paste API Platform code" (and keep our copyright thanks <3).
URI Variables came with this huge refactoring and re-visiting data retrieval on subresources. This lead to a quite natural extension point where all our logic resides:
core/src/Doctrine/Odm/State/ItemProvider.php
Line 62 in 92a81f0
core/src/Doctrine/Orm/State/ItemProvider.php
Line 67 in 92a81f0
While discussing with @divine, we thought it'd be a good idea to be able to change that part in the User-land.
Current implementation
Maybe this needs re-visiting, maybe that we need a new interface, but it'd need an ORM-specific signature... We already happen to have
ApiPlatfirm\State\Optionfor this?You really have all you need in that signature, but we could also move some of them in the
$context(entityClass and operation).Let me know your thoughts.