Better handle file upload
See original GitHub issueDescription
The procedure described on https://marmelab.com/react-admin/CreateEdit.html#altering-the-form-values-before-submitting is not possible to do using api-platform, because it encapsulate the dataProvider. So the access to the actions to be able to include a new header according to the data being sent is not possible without breaking the api-platform dataProvider code.
Example
To view the description on what I’m suggesting, please view https://marmelab.com/react-admin/CreateEdit.html#altering-the-form-values-before-
const dataProvider = {
// ...
create: (resource, params) => {
const { **dataHeaders**, ...record } = params.data;
const headers = new Headers({
'Content-Type': 'application/json',
});
**if (dataHeaders) { // This can be opinated. If data contains headers array, automatically set new headers on DataProvider
for(let i = 0; i < dataHeaders.length; i = i + 1 ) {
headers.set(dataHeader.name,dataHeader.value);
}
}**
return httpClient(`${apiUrl}/${resource}`, {
method: 'POST',
body: JSON.stringify(record),
headers,
}).then(({ json }) => ({
data: { ...record, id: json.id },
}));
},
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:15 (15 by maintainers)
Top Results From Across the Web
File Upload Protection – 10 Best Practices for Preventing ...
1. Only allow specific file types. · 2. Verify file types. · 3. Scan for malware. · 4. Remove possible embedded threats. ·...
Read more >File Upload - OWASP Cheat Sheet Series
File upload is becoming a more and more essential part of any application, where the user is able to upload their photo, their...
Read more >They all shall pass: a guide to handling large file uploads
As always, there are three ways to go: 1) Build large file handling functionality from scratch. 2) Use open-code libraries and protocols. 3) ......
Read more >9 Best File Uploader Solutions for Modern Applications
Uppy is a modular open-source, and sleek JavaScript file uploader that can fetch files from remote places like Instagram or Dropbox and locally....
Read more >Best way to handle file uploads through HTTP - Stack Overflow
Use Flash to queue up files and upload them one at a time to the server using the stanard file upload protocol. Use...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
API-Platform API and Admin components make very straightforward when creating CRUD operations on a resource. The basic flow involves creating an entity with the entity properties on the API side and the Resource component on the Admin site. This works great for any property you want to add to your entity.
If you would like that your entity holds a file property along others, you should only have to add a new property on the API side and a <FileUpload> component on the Admin side.
This is how it is supposed to work. But it won´t. You will need to prepare your API component to be able to handle it. Thankfully, the documentation handles it very clearly https://api-platform.com/docs/core/file-upload/#configuring-the-existing-resource-receiving-the-uploaded-file.
After you follow the docs and create the <FileInput> component on the Admin side, you will have a fully functional CRUD on the resource, right? Well, unfortunately not. The CREATE will work great WHEN you submit a file. But you will have two problems:
1 – when working on an UPDATE operation; 2 - when working on a CREATE (or UDPATE) operation but does not fill in the file field;
The first case will fail because the operation would be set to a PUT verb and the API Component is not configured to work with multi-part on PUT operation. This would rises a new issue because even if you choose to configure the PUT operation on the API component as you did on the POST, you will fall to a PHP restriction on file upload on PUT verb (https://www.php.net/manual/en/features.file-upload.put-method.php).
So, the workaround to solve the 1st situation would be to set, on the API component side, the PUT operation to accept the multi-part input format and to accept a POST verb instead of PUT default verb. Of course that would not comply to RESTfull verb, but it seams to be a PHP limitation.
This is how my operation configuration looked like after the configuration:
This workaround might be applicable by only updating the documentation. (I could submit a pull request, if acceptable.)
The problem in the second situation is that if the user does not fill in the file field on the client-side, the data that is delivered from the form to the DataProvider will not be filled in with the File object, and the Admin component will not change the content-type to a multi-part and instead will believe the form should be encoded to a JSON. The endpoint on the API component side will throw an error of not acceptable content type.
This is the use case we’ve been discussed previously on this case. I’ve managed to apply a workaround by using your suggestion and wrapping manually the dataProvider and forcing the content-type and verb for my resource.
But, giving a second thought, anytime you add a <FileInput> field in a Form on the Admin component side of an API-Platform app, you are already reducing your choices to a multi-part content type and POST verb. This is true because you know that is how API-Platform expects how to handle that. This is not the case on a vanilla react-admin app.
So a more elegant way would be that, by adding a <FileInput> field in, the ApiPlatform/admin automatically takes responsibility to make the changes of content-type and verb and you don’t need to apply for any work around on the dataProvider manually.
I thought in two ways this could be done:
I´m glad to help on trying to implement that but would like to know your thoughts if it is viable.
Just for the record, if someone faces the same situation, I´ve managed to solve by using the following code on the data provider:
Included support to the update operation. Available for your review on pull request #389. Best regards.