0
votes

I use api-platform for the first time and I am looking for the best way to upload files.

My situation : An entity "Post" with a OneToMany relation "Media" (SonataMedia) on server side, I'm working on the create view (Angular + Restangular).

All fields (except file type fields) are functional (persist OK). Now, for the file type fields, what do I have to do?

  • Asynchronous upload? in this case how to link files upload with my entity (which is not persisted yet)

  • upload files on form entity submit?

In every case, what it needs to send to server? How Api-platform manages it?

1

1 Answers

3
votes

There is no builtin file upload support as time of writing in API Platform. You need to write your own code to handle uploads. However, some work is some work being done to natively add this feature and you can already use it.

Basically, the idea is:

  1. Encode the file to upload as data: URI client-side (using JavaScript)
  2. Send this data URI (basically a base64 string) as a typical string entity property using Restangular (or any other HTTP client)
  3. Decode the data: URI server-side to a regular file using the Symfony Serializer
  4. Store this regular file on the server: it's up to you to store it on the filesystem or in more advanced backends such as Mongo GridFS or Amazon S3

Client-side

To get a data: URI client-side from a selected file, you can rely on the readAsDataURL of the FileReader JavaScript API: https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL. Send the resulting string as usual using Restangular.

Server-side

The API Platform normalization system is built on top of the Symfony Serializer. I've contributed a data: URI normalizer and denormalizer in Symfony: https://github.com/symfony/symfony/pull/16164 It is not merged yet but you can copy it in your own project during the meantime.

Register the normalizer:

services:
    data_uri_normalizer:
        class: 'AppBundle\Serializer\DataUriNormalizer'
        tags:
            - { name: serializer.normalizer }

Then create (and register) a new normalizer decorating the ItemNormalizer of API Platform to transform your property containing the file encoded as a data: URI to a standard \SplFileObject using the DataUriNormalizer::denormalize() method.

In a future version of API Platform (planned for the v2.1 with Symfony 3.1) all this logic will be automatically available and registered.