Question : custom POST operation that return Collection of Entities using API Platform extensions
See original GitHub issueHello,
I’m facing a problem, I can’t find a way to make a custom research POST endpoint using ApiPlatform :
Problem details
I need to make a big search query with a custom filter that takes an array of strings up to 300000 strings. This values represents an amount of approximately 4,29 MB of data. The query will return entities matching these strings by serializing them.
Example of current problematic request :
GET https://something.domain.tld/api/objects/search?thefilter=[123, 456, 789, lots of etc.]
The problem here as using this big filter in a GET request is it generates a huge URL that is not handled well by web browsers and lots of cloud providers services (ex : AWS Cloudfront). Cloud providers are restricting the URL size and headers size. Passing these values into a GET request body is not possible because lots of libraries and cloud providers services will block a such request.
I cannot pass these values into headers, URL parameters or into the request body of a GET request. I cannot split this query into multiple queries because this will result in too many queries.
Example of current expected behavior :
POST https://something.domain.tld/api/objects/search
PAYLOAD :
{
"the_filter": ["123", "456", "789", "lots of etc."]
}
Considered solutions
So, I am considering two options :
- Find a way to use a data provider with a POST request by injecting extensions into the data provider .
- Making a POST request with a custom controller that uses API Platform extensions (by injecting extensions : like injecting extensions into a data provider ?
Questions
I have 3 questions :
- Is there a way to call a data provider with a POST request without making API platform trying to INSERT something on the database ?
- Is there a way to make a POST request with a custom controller and uses API Platform extensions into the controller (Pagination and Filter) like this part of the documentation but in the controller ?
- If you have a more elegant solution, please suggest it 😃
Current progress
- I didn’t succeed to find a way to use dataprovider with POST request
- I suceed to find a way to inject API Platform extensions into a controller (edited)
Thanks a lot for reading, Best regards,
Issue Analytics
- State:
- Created 2 years ago
- Comments:7
Top GitHub Comments
After searching, a lot, I found a better solution :
Explantation
The get endpoint provides a standard API Platform search endpoint.
The POST endpoint is a sort of redirection that allows sending payload data to the standard API Platform GET endpoint by making the API call itself the GET endpoint with the payload data received by the POST endpoint.
Exemple code
The example endpoint definition in an entity :
The controller of the custom POST endpoint :
The custom openapi_context decorator
The custom decorator service definition :
Environment
This code was tested with :
API Platform : 2.6.5 PHP: 8
Pros
Approach caveat
@MaximeTaqt,
I did experimentations with DTO and it is working well. Input allow me do generate a documentation exemple of how to use the search endpoint and output is a reference to the auto generated GET endpoint schema.
For me, DataTransformer are a good solution, because they intend to transform data, so I use them to transform a search request to a Collection result ^^
In API Platform, we can use datatransformer to only transform an input DTO class to something that will be passed to a serializer class 😃
So this make DTO suitable because they are used to transform data and the Serializer is used after in this case 😃
It does respect the process according to the API Platform documentation and exemples : https://api-platform.com/docs/core/dto/
Here is an exemple of what I did :
My consts :
The entity :
The DTO class :
The DataTransformer class :
So the only caveat of this approach are :
The pros are :
Note: using custom controllers with API Platform is discouraged.