How does the REST API expect the "body"?

What’s the API expecting when using the “Upload” REST API?

I’m using CoronaSDK which of course isn’t officially supported, but I’ve had success using the other features of Backendless.

Here’s my code:


        if(event.target.id=="signupIcon")then
            -- Event handler for our asynchronous webcall
            -- (This one is pretty interchangeable for GET and PUT for now...)
            local function RetrieveUserData( event )
                if ( event.isError ) then
                    print("Network error!")
                else
                    print("Response "..event.response)
                end
            end     
            
            -- We'll need to adjust our headers to change the content type that
            -- Backendless expects...
            local params = {}
            params.headers = headers
            params.body = {filename = "test.txt",body = "the data that we crave"}
            -- To "upload text file to Backendless"
            network.request( "https://api.backendless.com/v1/files/test/test.txt", "POST", RetrieveUserData, params)
        end


I’m getting “Response {“message”:“The body is empty”,“code”:8011}”, yet I set the body here:

        params.body = {filename = "test.txt",body = "the data that we crave"}

I know I’m super close (If I delete that “filename” part, Backendless complains about a missing “filename” variable) so dang it, where do I stuff my data for the body??

Appreciate any pointers!

-Mario

Hi Mario,

The “body” in a REST request is expected to be in the “multipart/form-data” format. Please see this for details:

http://backendless.com/documentation/files/rest/files_file_upload.htm

Also, try running the “curl” command shown in the doc, you will see what the request is formatted like.

Hope this helps.

Regards,
Mark

I’ve got the docs page, that’s what I’ve been banging my head against the whole evening. I guess I’m trying to figure out the datastruct that it’s expecting me to pass my actual data in…a key value pair perhaps? Also, no idea how to run CURL commands, sorry. I am a total newb. Orchestrate I’ve got working, I was excited about Backendless too…just hitting a brick wall.

If I could get an example of JSON formatted struct of the “body” that would come in handy, or a URL encoded version of the call?

-Mario

Google for an overview of multipart/form-data. For example:
http://chxo.com/be2/20050724_93bf.html

curl works beautifully on Linux or Mac os x. Not sure about Windows.

{filename = “test.txt”,body = “the data that we crave”}

Is not valid JSON, should probably be

{“filename” : “test.txt”,“body” : “the data that we crave”}

Note the extra " and the = should be :

I was wondering though if the API is expecting JSON though? Cause in LUA I can just run a json.encode to convert the data to JSON, I just can’t figure out how it wants the body packaged.

The above example is just a table struct in LUA, so it wasn’t intended to be proper JSON… :slight_smile:

Appreciate the tips so far people, I’m going to be pretty bummed out if I can’t upload text or picture files using the REST API so I’ll keep hacking away on it…

-Mario

OK Never mind, finally got it figured out. Had to roll my own (or more accurately, borrow someone else’s!) multipart encoder in LUA. w00t! Got my files uploading and downloading now with no problems! Corona’s LUA only will transmit base64 encoded data but it’s all good with the built-in encode/decode commands.

[reply user_id=187][h4]Mario Roberti wrote:[/h4]OK Never mind, finally got it figured out. Had to roll my own (or more accurately, borrow someone else’s!) multipart encoder in LUA. w00t! Got my files uploading and downloading now with no problems! Corona’s LUA only will transmit base64 encoded data but it’s all good with the built-in encode/decode commands.[/reply]Hi Mario can you share the code for upload and download the image using Corona sdk?
Thanks

Yeah I’ll try to dig it up later today. Stay tuned!

-Mario

OK, here’s what I got and confirmed it’s still working…some caveats though remember that base64 encode will mean NO VIEWING THROUGH A WEBPAGE; you’ll need to download the images and decode them with the “decode” commands…can’t find my source to do that right now, but I’m attaching the needed file (Credit goes to whoever made it, I altered it and banged it with a hammer until it worked!)

Also, adjust the target directories and your source directories, of course.

Ping me if you need more help!




    local MultipartFormData = require ("multipartForm")
    local headers = {}
    headers["application-id"] = "your stuff here"
    headers["secret-key"] = "your stuff here"
    headers["Content-Type"] = "application/json"
    headers["application-type"] = "REST"
    
    
    local params = {}
    -- Event handler for our asynchronous webcall
    local function ConfirmUpload( event )
        print("Upload attempt completed....")
        if ( event.isError ) then
            print("Network error!")
        else
            print("Result: "..event.response)
        end
    end     


    
    -- We'll need to adjust our headers to change the content type that
    -- Backendless expects...
    
    local multipart = MultipartFormData.new()
    multipart:addHeader("application-id", "your stuff here")
    multipart:addHeader("secret-key", "your stuff here")
    local filename = "assets/signup.png"          
    multipart:addFile("myfile", system.pathForFile(filename, system.ResourceDirectory ), "image/png", filename)
    
    params.body = multipart:getBody() -- Must call getBody() first!
    params.headers = multipart:getHeaders() -- Headers not valid until getBody() is called.
    
    --  Upload image to Backendless
    network.request( "https://api.backendless.com/v1/files/moist/"..filename, "POST", ConfirmUpload, params)

multipartForm.zip (1.87kB)