I have been coding an API for a photo sharing app like Instagram using Symfony2, FOSRESTBundle, and Vichuploader for file uploads.
I'm able to work around GET and POST requests, but I can't find an example of how to attach to a POST request, the actual image so that in my case, Vichuploader can grab it and help me out with the file upload.
By the way, I can upload a file without issue using the stack mentioned through the use of a normal form.
You use form types for posts with the FOSRestBundle:
For example you have this form type:
Then what you can do is post JSON to the API. Don't forget to set the header as "Content-type = application/json" when you do a POST.
The JSON structure would look like this:
}
Why is this json wrapped in "data"? Because your form type also has "data" in getName so it will use validation and etc.
What I always do is I encode my pictures as a base64 string while sending them to the API.
Then in the post function you just convert it back:
I have been looking for a solution about the exact same problem. Here is what I did.
First let me explain my constraints. I wanted my API to be full JSON and to take power of the HTTP protocol (headers, methods, etc.). I chose to use:
First solution envisaged: base64
My first thought, because I was thinking JSON everytime, was to encode all the incoming images in base64, then decode them inside my API and store them.
The advantage with this solution is that you can pass images along with other data. For instance upload a whole user's profile in one API call. But I read that encoding images in base64 make them grow by 33% of their initial size. I did not wanted my users to be out of mobile data after sending 3 images.
Second solution envisaged: form
Then I thought using forms as described above. But I did not know how my clients could send both JSON data (for instance
{"last_name":"Litz"}
) and image data (for instanceimage/png
one). I know that you can deal with anContent-Type: multipart/form-data
but nothing more.Plus I was not using forms in my API since the beginning and I wanted it to be uniform in all my code. [mini-edit: hoho, something I just discovered, here]
Third and last solution: use HTTP..
Then, one night, the revelation. I'm using
Content-Type: application/json
for send JSON data. Why not useimage/*
to send images? So easy that I searched for days before coming with this idea. This is how I did it (simplified code). Let suppose that the user is callingPUT /api/me/image
with aContent-Type: image/*
UserController::getUserImageAction(Request $request) - Catching the Request
UserImageService::updateUserImage($user, $content) - Business Logic (I put everything here to be simplier to read)
This is a full upload from api code bit. This does upload the file, but I am still having trouble with validating the uploaded file. Hope this helps.
This uses fosrest bundle for REST.
An example for a upload method exepting post requests:
So this action first stores the document on the server and returns a json response containing document meta data and path. I used the response for further processing in my web application.
I am not familiar with VichUploader, the above code is native Symfony2 code using Symfony\Component\HttpFoundation\File\UploadedFile.
Read: http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html