Now that we've seen how to distribute files, let's move on to the other focus, how to securely upload them!
The API defines an endpoint where the clients send a POST request with the file data:
/product:
post:
# ...
summary: Add a new product
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
image:
type: string
format: binary
file:
type: string
format: binary
# ...
Note the image
and the file
properties inside the request body. As the content type is multipart/form-data
, this is the standard way to upload binaries: add file inputs to a form and the browser will send them when the form is submitted.
Implementation here.
On the frontend, a fetch
assembles a FormData
object and posts to the endpoint:
// add image and file to the form data
if (formData.get("image")) {
formData.set(
"image",
document.querySelector("#imageInput").files[0]
);
}
if (formData.get("file")) {
formData.set(
"file",
document.querySelector("#fileInput").files[0]
);
}
const req = await fetch(
"/api/product",
{
method: "POST",
headers: {
authorization: "Bearer " + await getAccessToken()
},
body: formData,
}
);
Using a fetch
is needed in this case as the endpoint requires authentication and that is dependent on the Authorization
header. Were it to use cookies then this step would not be needed.
Implementation here.
To make a robust implementation on the backend, we'll need to handle a few things. First, the binaries should be streamed to files instead of read fully and then written. Then we'll see how to propely handle errors so that no leftover files are left when there is an error during the upload. Then we'll see how to update the database.
Implementation here.