-
-
Notifications
You must be signed in to change notification settings - Fork 865
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(doctrine): stateOptions can handleLinks for query optimization #5732
Conversation
57b5273
to
e13f29d
Compare
I love the idea! |
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! |
I need to add a way to call services for that to work! |
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: new Options(handleLinks: [Employee::class, 'handleLinks'])
)] Not really relevant for this PR itself, but probably relevant for the documentation of this new feature. |
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. |
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! |
I'm curently adding a service locator to improve this a bit |
ca5bcea
to
aef6e86
Compare
} | ||
|
||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): iterable | ||
{ | ||
$resourceClass = $operation->getClass(); | ||
$documentClass = $operation->getClass(); | ||
if (($options = $operation->getStateOptions()) && $options instanceof Options && $options->getDocumentClass()) { |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 :|.
a7dd210
to
927ab07
Compare
927ab07
to
c33fa22
Compare
c33fa22
to
111a066
Compare
First, this patch allows
stateOptions: entityClass
to 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\Option
for 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.