{"id":27962570,"url":"https://github.com/jangerhofer/serverlesss3upload","last_synced_at":"2025-05-07T19:24:06.019Z","repository":{"id":87680931,"uuid":"84279919","full_name":"jangerhofer/serverlessS3Upload","owner":"jangerhofer","description":"Example of using the Serverless framework to upload files to S3.","archived":false,"fork":false,"pushed_at":"2023-12-15T11:42:15.000Z","size":7,"stargazers_count":35,"open_issues_count":5,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2023-12-15T12:46:45.657Z","etag":null,"topics":["aws","s3","serverless"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jangerhofer.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-03-08T04:53:18.000Z","updated_at":"2021-10-02T23:02:48.000Z","dependencies_parsed_at":"2023-03-17T14:00:14.788Z","dependency_job_id":null,"html_url":"https://github.com/jangerhofer/serverlessS3Upload","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangerhofer%2FserverlessS3Upload","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangerhofer%2FserverlessS3Upload/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangerhofer%2FserverlessS3Upload/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangerhofer%2FserverlessS3Upload/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jangerhofer","download_url":"https://codeload.github.com/jangerhofer/serverlessS3Upload/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252942127,"owners_count":21829008,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","s3","serverless"],"created_at":"2025-05-07T19:24:05.477Z","updated_at":"2025-05-07T19:24:06.001Z","avatar_url":"https://github.com/jangerhofer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serverless Direct S3 File Upload\n\nThis example uses the [Serverless](https://serverless.com/) framework to show how sites can enable visitors to upload files directly to [S3](https://aws.amazon.com/s3/), rather than through a webserver.\n\n## Why use the direct upload pattern?\nFile uploads are a common website feature however it is not immediately apparent how to build them when using the [Serverless stack](https://angerhofer.co/posts/tags/serverless).  In a traditional model, a web server receives the upload from the client/browser and sends it along to storage (whatever form that may take -- e.g. saved on disk, saved _into_ a database, uploaded to S3, etc.).\n\nThis is a relatively time-intensive task for the web server, so S3 introduces an alternative: temporary access privileges.  This alternate pattern has two steps.  First, the [Lambda](https://aws.amazon.com/lambda/) function asks S3 through our IAM credentials for a public link that will let the browser upload the file directly to an S3 bucket.  It returns this link to the browser, which subsequently `PUT`s the file to the link and completes the upload.\n\nThis model takes a fair bit of load off our Lambda functions without sacrificing the security of the upload, saving otherwise significant costs.\n\n## Why S3?\nThere are a plethora of good reasons to use S3 to store your application's file uploads and you can find a much more exhaustive rundown with a quick Google search than I could hope to describe here.  In short, S3 takes all the fretting out of storing, serving up, and backing up you application's files.\n\n## Public Link Mechanism\n[Line 23 in `handler.js`](https://github.com/jangerhofer/serverlessS3Upload/blob/master/handler.js#L23): `var uploadURL = s3.getSignedUrl('putObject', s3Params);`\n\n[This method](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property) asks S3 to generate a single-use link that will allow a browser that is NOT authenticated with AWS to upload a specific file (as specified by the `POST` request outlined below) to the application's S3 bucket.  That way, the file being uploaded never touches the Lambda server and instead goes directly from the browser into storage.\n\n## Usage\n_Assuming AWS credentials and Serverless are already configured properly._\n- `npm install` the two dependencies.\n- Replace the `[bucketName]` placeholder in both `handler.js` and `serverless.yml` with the desired bucket in which uploads will be stored.\n- `serverless deploy` the service to AWS.\n- `POST` to the API Gateway endpoint to generate a single-use upload link. _N.b. If either of these parameters does not match the file which is uploaded in the next step, S3 will throw an error and refuse the upload._\n  - `POST` should have two `x-www-form-urlencoded` paramters:\n    - `name`: Filename to be uploaded.\n    - `type`: [MIME Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) of file.\n- Create a `PUT` request via your interface of choice (e.g. AJAX call, [Postman](https://www.getpostman.com/) request, or curl).  The URL will be the result from the previous `POST`.  Attach the file Blob/binary to the request and specify the proper headers for the `Content-Type`.\n  - e.g. in Curl:\n  ```\n  curl -v -H 'Content-Type: image/png' -T ./testFile.png \"https://[bucketName].s3.amazonaws.com/testFile.png?long_query_string...\"\n  ```\n\n  Et voila!  Your bucket should now have the new file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjangerhofer%2Fserverlesss3upload","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjangerhofer%2Fserverlesss3upload","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjangerhofer%2Fserverlesss3upload/lists"}