Problem uploading file via REST API

  • Goal: I'm trying to submit a file to a server via REST api. The file is should be selected by the user.

  • Steps: I created a form with file button or file drop zone (I tried both with the same result) and in the rest api query I selected "Form data" body type and I created a field for a file with a file type. In that field I've tried to put different things, such as:
    {{ fileButton1.value[0] }}
    or as suggested in another thread on this forum:
    {{ { data: fileButton1.value[0], ...fileButton1.files[0] } }}
    In both cases, on my server I receive request body like following:
    ----------------------------966856257142209492270841
    Content-Disposition: form-data; name="file"

[object Object]

----------------------------966856257142209492270841--

If I put {{ fileButton1.value[0] }}, the result is exactly the same. How can I submit the file using a REST request??

one of the the below should work for you, it should depend on what content-type the server endpoint is expecting and possibly the type of file being sent.

if the file is NOT an image, audio or video file, ect you can try {{ JSON.stringify(fileButton1.value[0] }}


using the declared type File:
image
actually expects an array of objects as a string using the below format

"[
  {
    base64Data: "",
    name: "",
    sizeBytes: 0,
    type: "application/pdf"
  }
]"

the .value of the file components should already be in the format you need, including the array, all you need to do is convert it to a JSON string.

otherwise if it's still complaining the issue is probably on the server side and it's expected content-type is different so I'd try changing the Body type to Binary instead of Form Data and use {{ fileButton1.value[0] }}

I'm using test server (mockbin) to just see what request is being sent and if you take a look at my second screenshot you will that the Conetnet-type is multipart/form-data as expected by the file param instead of a file contant contains a string "[object Object]"

ya, all object properties in every external request (including webhook workflows) will be a string. JS doesn't natively provide built-in type casting for object types, which is why you're seeing the type as a string and why I think using

{{ JSON.stringify(fileButton1.value[0] }}

should fix the problem.

the other possibility was to set the request Body to Binary and use the value given as-is and hope it's right with

{{ fileButton1.value[0] }}

on the server side, it can only receive 0's and 1's, cause computers (ignore quantum ones), so in order to know what to translate these as it reads the Content-Type and Content-Disposition headers. when we use form-data, image/png, application/pdf or something we're telling the server the 0s and 1s are in a pattern that represents a specific type of file which JS or Python can properly read as a variable in code(still on the server side). when we use application/octet-stream it's too vague for the server to know what was sent, so it defaults to assuming the 0s and 1s are in a pattern that represent some kind of filetype that the OS can read (i.e. it tells the server to create a new file with the data sent instead of holding a representation of a file as a variable in JS). as a result of saving the file on disk, we hope the OS can tell us the file type and if it can't it uses the most generic type possible that can only be read as binary data:

This doesn't do the job at all. With this in place it seems that retool sends no request body. Here are the headers received by mockbin. As you see content length is 0.


And indeed the body is just empty:

So going back to my original question:

What is the correct expression that I should put as the "file" value, so that retool sends a proper form/multipart request with the actual file that was chosen by the user??

It seems that there is a bug in retool cause according to the documentation:


I should be able to put {{ fileInput.value }}. However when I do this, this is what I get on my server:

So it seems as retool does not handle the file upload as it's supposed to according to the documentation entry pasted above. Can any retool developer explain this?

Worked fine for me:


As shown in one of your screenshots, there is an guide to handling files in Retool here: Interact with files | Retool Docs