Upload Files To S3 Using Lambda and API Gateway (SERVER LESS)

Uploading files to S3 can be sometimes tough especially if you have a serverless project.

We will be using pre-signed URLs, Lambda Functions and API Gateway for this process.

STEP 1

Create a S3 bucket where you want to store your files.Also edit the CORS configuration of the bucket.

<?xml version=”1.0" encoding=”UTF-8"?>
<CORSConfiguration xmlns=”http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>WRITE ORIGIN OR PUT * FOR TESTING</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>WRITE ORIGIN OR PUT * FOR TESTING</AllowedHeader>
</CORSRule>
</CORSConfiguration>

The above configuration will allow GET and PUT requests to intract with your bucket, form the web browser.

STEP 2

Create policies and role for Lambda via AWS IAM, so that Lambda can generate the URL.

IAM POLICY

Now add this policy to a role for Lambda, also add AWSLambdaBasicExecutionRole to the Lambda role, so that you can monitor your function on cloud watch.

STEP 3

Create a Lambda function, attach the above role to it.The following code takes the filename (key) from the API Gateway and generates a signedURL.

const AWS = require('aws-sdk');
const s3 = new AWS.S3({signatureVersion: 'v4'});
exports.handler = async (event,context) => {
const bucket = process.env.BUCKET_NAME;
const key = event.key;
const params = {
Bucket: bucket,
Key: key,
ContentType: 'multipart/form-data’,
Expires: 60
};
try{
const signedURL = await s3.getSignedUrl(’putObject’, params);
const response = {
err:{},
body:"url send",
url:signedURL
};
return response;
}catch(e){
const response = {
err:e.message,
body:"error occured"
};
return response;
}
};

STEP 4

Create an API Gateway, and make this API a trigger to above created lambda function. Ensure the CORS setting of the API is updated.

STEP 5

Testing the FILE upload.
First make a POST request to the API, with filename (EX- File.txt) as body of the request i.e (key:File.txt), the API will see this filename and Lambda function will generate a URL according to the filename and send this URL back as response.
We have to then send a PUT request to the received URL with correct headers. Body of the request will be having the file itself as multipart/formdata.

const options = {
headers: {
"Content-Type": "multipart/form-data"
}
};
// inside an async function
const res = await axios.put("URL",Your-File,options);
console.log(res);

ALL DONE