Upload files to amazon s3 bucket in NodeJS
Prerequisties:
- Express app with multer for receiving image from front end
- Create aws account and go to s3 then create bucket where you can get the credentials.
- Install aws-sdk package
- 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 (req, file, callback) {
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_ACCEPTABLE, true);
return callback(err);
}
callback(null, true)
},
limits: {
fileSize: 2 * 1024 * 1024
}
}).single('upload');
/**
* Upload image using nulter.
*/
function uploadMulter(req, res, next) {
return new Promise(function (resolve, reject) {
upload(req, res, function (err) {
if (err) {
if (err.code === 'LIMIT_FILE_SIZE') {
err = new APIError('File size must be less than 2MB.', httpStatus.NOT_ACCEPTABLE, true);
}
return next(err);
}
// No error occured.
resolve(req.file.filename);
});
})
}
/**
* function to upload to aws s3
* @param {string} filename
* @param {string} folder
*/
function sendToS3(filename, folder) {
return new Promise(function (resolve, reject) {
fs.readFile(uploadRootFolder + folder + '/' + filename, function (err, file) {
if (err) reject(err);
var data = { Key: folder + '/' + filename, Body: file, ACL: 'public-read' };
s3.upload(data, function (err, data) {
if (err) reject(err);
resolve(data);
});
})
})
}
function receiveFile(req,res,next){
uploadMulter(req, res, next)
.then(function (result) {
//call to upload original file
return sendToS3(result, 'uploadFolder')
})
.then(function (result) {
res.send(result.Location);
})
.catch(error => next(error))
}