Core: Quick Clarification on DataProviders for subresources

Created on 9 Nov 2018  路  3Comments  路  Source: api-platform/core

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.

Most helpful comment

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.

All 3 comments

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?

Was this page helpful?
0 / 5 - 0 ratings