17
I’ve been having second thoughts about it for almost a month. In certain to my application, the user can upload to a file library.
This upload needs to be recorded in a table called midias
, where, in addition to the file path, I also need extra data such as name, description, file permission, and metadata information such as file size and extension.
The question that arises in this case is the following: For the record in the database referring to this file, I also need the other information. And, as the requests usually use the content-type JSON, I wonder how the file would be sent then, since the JSON have some limitation as to the characters that can be included in the same.
Hypothetical example:
POST /api/midias/
Content-Type: application/json
{
"nome" : "Flor",
"descricao" : "A flor azul encontrada na
"tipo_acesso" : 1,
"extensao" : "jpg",
"tamanho" : 5225,
"arquivo" : ???????
}
That is, according to example above, to create the resource in my API, in addition to the media information, I also needed to send the binary file, to upload.
Now let’s get down to business:
1) The first way I tried was to send the binary of a file via JSON
even, converting the file binary to base64
.
Base64’s problem is that it increases (and greatly) the file size, making it unviable in my case, since we will allow uploading videos.
2) Use the multipart/form-data
, sending the file normally, as is done in form requests, and attaching the other data cited above in a field "json"
, sending this data as a string JSON
(serialized).
Example:
POST / HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:29.0) Gecko/20100101 Firefox/29.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: __atuvc=34%7C7; permanent=0; _gitlab_session=226ad8a0be43681acf38c2fab9497240; __profilin=p%3Dt; request_method=GET
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
Content-Length: 554
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="json"
{"nome" : "Flor", "descricao" : "..."}
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
Content of a.txt.
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html
<!DOCTYPE html><title>Content of a.html.</title>
-----------------------------9051914041544843365972754266--
As far as I can see, this is outside the standard that is already being used in all other requests, which is the content-type: application/json
, as well as being a very dirty girl.
3) Separate file upload logic from media data upload.
This seemed the most pleasant and, from what I read and talked about, seemed more organized. But I’ve never done anything like this, having no implementation experience, and I also don’t know if this is a standard in REST.
One of the tips I saw, for example, was to upload the file, return the ID
this upload, to be used in sending the "extra data" to create the resource on the server referring to this file.
My question is:
Of the above options, which one would be closer to REST?
If it is feasible to implement the third option, there is some standard to define the
content-type
file and what kind of response status I could return?
I would like to have a few examples on the third option, since it was the only one I did not implement, and I have no idea how to do something similar.
In my view, the third option can cause a serious problem: inconsistency or data anomaly. Allowing data to be entered by parties has some problems, what if the device shuts down after the first request and before starting the second? How it will be validated so that a malicious user does not register several times a part only of the data, which can cause some 404 and ordinary users do not understand anything
– Costamilam
@Guilhermecostamilam but the idea was actually to create, for example, a table that would assign the upload to a user. I would return the
id
of that "upload" for the user to associate it to the "metadata" that would need to be sent along with the file, After creating the resource data, it would move the file on the server to where it wanted, since the new request would inform theid
of that file and then delete the resource from the old file created.– Wallace Maxters
That would make the feature more complicated, what if he sends the file and doesn’t pass the metadata later? Will you keep a useless file on your server? Will you create a routine to delete those that exceed 24 hours? I’m not saying it’s the worst, but the most complex, maybe a simpler alternative is preferable
– Costamilam
I was in doubt, send the data json by the body of the request has limit? It escapes from the standard Rest?
– Ismael SIlva