This project demonstrates a serverless approach to handling image uploads via a static website. Users can upload an image (JPG/PNG/JPEG/GIF), which is then automatically resized by AWS backend services, and a download link for the resized version is provided.
The process leverages several AWS services orchestrated via API Gateway and Lambda:
- Static Website (AWS S3): The user interacts with an HTML/CSS/JavaScript frontend hosted as a static website on an S3 bucket (
shayan-image-uploader-web). - API Request (API Gateway + Lambda #1):
- When the user selects a file and clicks "Upload", the JavaScript sends a request containing the filename and content type to an API Gateway endpoint (
/generate-upload-url). - This triggers the Lambda function code inside of
generate_upload_urlfolder. - This Lambda function does not handle image data directly. It generates two S3 Presigned URLs:
- A
PUTURL allowing the browser to upload the original image directly to the source bucket (shayan-image-uploads-source) under a unique key (e.g.,uploads/...). - A
GETURL that will allow the browser to download the resized image later from the destination bucket (shayan-image-resized-destination), using a predicted key (e.g.,resized/...).
- A
- These two URLs are returned to the browser.
- When the user selects a file and clicks "Upload", the JavaScript sends a request containing the filename and content type to an API Gateway endpoint (
- Direct S3 Upload (Browser -> S3):
- The JavaScript uses the received presigned
PUTURL to upload the image file's raw data directly from the browser to theshayan-image-uploads-sourceS3 bucket. This bypasses API Gateway/Lambda for the heavy lifting of the upload.
- The JavaScript uses the received presigned
- S3 Trigger (S3 -> Lambda #2):
- The successful upload of the original image into the
shayan-image-uploads-sourcebucket automatically triggers the Lambda function code inside ofimage_resizer_s3folder (configured via S3 Event Notifications).
- The successful upload of the original image into the
- Image Resizing (Lambda #2):
- The
S3TriggeredResizeFunctiondownloads the original image from the source bucket. - It uses the Pillow (PIL) library to resize the image to predefined dimensions (e.g., max width 256px, maintaining aspect ratio).
- It uploads the resized image file to the
shayan-image-resized-destinationS3 bucket, using the key structure predicted by the first Lambda function.
- The
- Download Link Activation (Frontend):
- Once the direct S3 upload (Step 3) completes, the JavaScript displays the download link (using the presigned
GETURL received in Step 2). - Important: A short delay is implemented before the download link becomes clickable. This allows time for the asynchronous resize process (Steps 4-5) to complete in the background.
- Once the direct S3 upload (Step 3) completes, the JavaScript displays the download link (using the presigned
- Download (Browser -> S3):
- When the user clicks the activated download link, the browser uses the presigned
GETURL to fetch the resized image directly from theshayan-image-resized-destinationbucket.
- When the user clicks the activated download link, the browser uses the presigned
- Navigate to the static website hosting URL:
http://shayan-image-uploader-web.s3-website.us-east-2.amazonaws.com. - Click the "Choose File" button and select a JPG/JPEG/PNG image from your local machine.
- Click the "Upload Image" button.
- Observe the status messages and the progress bar indicating the direct upload to S3.
- Once the upload completes, the status will indicate processing, and a download link will appear (initially greyed out/disabled).
- Wait a few seconds for the link to become active (the status message will update).
- Click the download link to save the resized image.
- Asynchronous Processing: The image resizing happens in the background after the initial upload completes. The delay before the download link activates is necessary to account for this processing time. Without the delay, clicking the link too early would result in an error as the resized file wouldn't exist yet.
- Ad Blockers / Browser Extensions: Some browser extensions (particularly content/ad blockers or privacy tools like
FilterContent) may interfere with the JavaScript execution or the direct S3 upload/download process. They can sometimes cause console errors that are unrelated to the application's core logic. If you encounter unexpected issues, try testing in an Incognito/Private window or temporarily disabling extensions. - Error Handling: Basic error handling is implemented, but a production-ready application would require more comprehensive checks and user feedback mechanisms.