Not necessarily bug but a case of either missing documentation or unexpected behaviour.
Apologies if I'm missing something but I cant find anything in documentation or existing issues that match my thinking.
Would appreciate anyone with subresources experience to shed some light on this.
My scenario:
I use API Entities as plain DTOs, I dont use doctrine at the API Platform layer, my intention is to have a custom data provider/persister mapped to every action and have API Platform essentially only responsible for the HTTP layer and serializing/deserializing request/responses.
Assumption:
DataProviders/DataPersisters are used as a native method to provide custom methods of providing/persisting data for Entities.
My assumption would be that this would be a standard pattern for how to provide/persist entities wether they are top level resources or subresources.
Reality:
From what I've seen in my findings, DataProviders (not looked at Persistance side of things yet) are not used at all for subresources.
And the only way to map a custom method of providing an Entity that is a subresource, is a Controller action.
ie. GET /user/123/messages triggers neither the User nor Message data provider.
Question:
I want to have a custom Provider/Persister for subresources, is the only way to achieve this via a controller action? (ignoring kernel events)
Many thanks for any help I dont like creating github issues for simple queries but I've just hit a brick wall with trying to debug if custom DataProviders are even part of the equation with subresources.
Further investigation I have discovered SubresourceDataProviderInterface but unfortunately there is no documentation on this.
Applying this to a DataProvider will have API Platform check this DataProvider when trying to load a subresource. It raises another issue though as theres no clear reference to the root entity class.
With 2 entities User and Message, Message being a subresource of User, ie /user/123/messages
The $resourceClass given to the DataProvider is Message and the only reference to the root resource of User is under the $context['subresource_resources'] array, which I assume would contain all the resources above the current subresource attempting to be retrieved, I have not tried this myself personally yet. ie /company/1/staff/2/jobs would have the company and staff entities with their identifiers in that $context['subresource_resources'].
So the provider code will need to manually filter these out.
I'm gonna do a bit more playing around now I've discovered this but I'll likely close this ticket soon as this satisfies my original intentions.
Closing as the clarification is essentially:
Resources, wether they are root /users or subresources /company/1/users are sent to the same data provider. So its the data provider's responsibility as far as I can tell, to identify its a subresource call, and manage the query accordingly.
I LOVE YOU, can't this be added to the official documentation?
Most helpful comment
Further investigation I have discovered
SubresourceDataProviderInterfacebut unfortunately there is no documentation on this.Applying this to a DataProvider will have API Platform check this DataProvider when trying to load a subresource. It raises another issue though as theres no clear reference to the root entity class.
With 2 entities
UserandMessage,Messagebeing a subresource ofUser, ie /user/123/messagesThe
$resourceClassgiven to the DataProvider isMessageand the only reference to the root resource ofUseris under the$context['subresource_resources']array, which I assume would contain all the resources above the current subresource attempting to be retrieved, I have not tried this myself personally yet. ie /company/1/staff/2/jobs would have the company and staff entities with their identifiers in that$context['subresource_resources'].So the provider code will need to manually filter these out.
I'm gonna do a bit more playing around now I've discovered this but I'll likely close this ticket soon as this satisfies my original intentions.