images
17th May, 2019

Upload files to amazon s3 bucket in NodeJS

Prerequisties:

  1. Express app with multer for receiving image from front end
  2. Create aws account and go to s3 then create bucket where you can get the credentials. 
  3. Install aws-sdk package
  4. In .env file add

·         AWS_ACCESS_KEY_ID=xxx

·         AWS_SECRET_ACCESS_KEY=xxx

·         S3_BUCKET=xxx

 

In backend, create upload.controller.js which will handle the receiving of the file and upload to s3 then response back with url of the image.

const aws = require('aws-sdk');

/*

 * Configure the AWS region of the target bucket.

 * Remember to change this to the relevant region.

 */

aws.config.region = 'ap-southeast-1';

aws.config.accessKeyId = process.env.AWS_ACCESS_KEY_ID;

aws.config.secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;

 

var s3 = new aws.S3({ params: { Bucket: process.env.S3_BUCKET} });

 

const path = require('path');

 

var upload = multer({

    storage: storage,

    fileFilter: function (reqfilecallback) {

        var ext = path.extname(file.originalname).toLowerCase();

        if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {

            const err = new APIError('Only images are allowed'httpStatus.NOT_ACCEPTABLEtrue);

            return callback(err);

        }

        callback(nulltrue)

    },

    limits: {

        fileSize: 2 * 1024 * 1024

    }

 

}).single('upload');

 

 

/**

 * Upload image using nulter.

 */

function uploadMulter(reqresnext) {

    return new Promise(function (resolvereject) {

        upload(reqresfunction (err) {

            if (err) {

                if (err.code === 'LIMIT_FILE_SIZE') {

                    err = new APIError('File size must be less than 2MB.'httpStatus.NOT_ACCEPTABLEtrue);

                }

                return next(err);

            }

            // No error occured.

            resolve(req.file.filename);

        });

    })

}

 

/**

 * function to upload to aws s3

 * @param {string} filename

 * @param {string} folder

 */

function sendToS3(filenamefolder) {

    return new Promise(function (resolvereject) {

        fs.readFile(uploadRootFolder + folder + '/' + filenamefunction (errfile) {

            if (errreject(err);

            var data = { Key: folder + '/' + filenameBody: fileACL: 'public-read' };

            s3.upload(datafunction (errdata) {

                if (errreject(err);

                resolve(data);

            });

        })

    })

}

 

function receiveFile(req,res,next){

    uploadMulter(reqresnext)

        .then(function (result) {

            //call to upload original file

            return sendToS3(result'uploadFolder')

        })

        .then(function (result) {

            res.send(result.Location);

        })

        .catch(error => next(error))

}