Uploads are implemented to use a 3-step process. First, the frontend requests an upload URL to a staging area. Second, it uploads the file. And third, it makes a call to the backend notifying it about the newly uploaded file.
While it seems like an unnecessarily complicated process, it handles a lot of edge cases. The database is not updated until the third step, so if at any time the client terminates the process then nothing is changed and the file is eventually deleted. We'll discuss the motivation behind this process in the Uploading files chapter.
This multi-step process is a marked difference from the server-based solution. With a central server, the API for uploading files is not that different from the endpoint for downloads. This was due to the server's ability to handle both the file uploads and the database updates so only a single request was enough.
But in a serverless environment, these two operations are separated: S3 handles the file uploads while the backend needs to update the database.
The process for uploading new promo images and deliverable files are similar. There is a small difference in regards to content types, which we'll discuss later, but most of this chapter focuses on the promo images.
To get a signed URL, the backend offers an endpoint:
/product/getImageUploadURL: get: # ... security: - cognito:  summary: Get upload URL for an image responses: '200': description: successful operation content: application/json: schema: type: object properties: url: type: string format: url example: https://bucket.com/key2 fields: type: object additionalProperties: type: string
This is an authenticated operation (
security: - cognito: ) which means only logged-in users can call it.