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