How to Use S3 File Storage with Node.js and AWS SDK for Efficient File Management
Learn how to store and manage files in AWS S3 using Node.js with the AWS SDK client.
NodejsFeb 27, 2024Nagesh

Dependencies
Json
"dependencies": {
"@aws-sdk/client-s3": "^3.382.0",
"aws-sdk": "^2.1427.0",
"multer": "^1.4.5-lts.1",
"multer-s3": "^3.0.1",
},
Config
Javascript
{
AWS_BUCKET_NAME: process.env.AWS_BUCKET_NAME,
s3Config: {
credentials: {
accessKeyId: process.env.S3_BUCKET_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_BUCKET_SECRET_ACCESS_KEY,
},
region: 'ap-south-1',
logging: true
}
}
Creating S3 Storage
Javascript
const { S3Client } = require('@aws-sdk/client-s3')
const multerS3 = require('multer-s3');
const { AWS_BUCKET_NAME, s3Config } = require('../../config');
// Configure your AWS credentials and region
const s3 = new S3Client(s3Config);
const s3Storage = (subDirectory) => {
return multerS3({
s3: s3,
bucket: AWS_BUCKET_NAME,
acl: 'public-read', // Set the ACL permissions for the uploaded file
key: function (req, file, cb) {
const filepath = `user/${req.user._id}/${subDirectory}/`;
const filename = Date.now().toString() + '-' + file.originalname;
const fullpath = filepath + filename;
cb(null, fullpath);
},
});
}
module.exports = s3Storage;
Creating Multer middleware Using S3 storage
Javascript
const multer = require('multer');
const s3Storage = require('../utils/multer/s3Storage');
const { acceptImageFileType } = require('../utils/multer/acceptImageFileType');
const uploadImage = (subDirectory) => {
return multer({
storage: s3Storage(subDirectory),
limits: {
fileSize: 3000000 // bytes same as 3MB
},
fileFilter: function (req, file, cb) {
acceptImageFileType(file, cb);
}
});
}
module.exports = uploadImage;
Optional Filter file type
Javascript
const path = require('path');
function acceptImageFileType(file, cb) {
// Allowed filetypes
const filetypes = /jpeg|jpg|png/;
// Check extension
const extname = filetypes.test(
path.extname(file.originalname).toLowerCase()
);
// Check mimetype
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Images Only!');
}
}
exports.acceptImageFileType = acceptImageFileType;
using using image upload middleware on route
Javascript
router.post(
"/user-profile-cover",
uploadUserImage('profileCover').single("file"),
updateProfileCover
);
Handling image link on controller
Javascript
module.exports.updateProfileCover = async (req, res) => {
try {
// Check if file is present in the request
if (!req.file) {
return error({ res, msg: strings.pleaseUploadImage });
}
const user = await User.findById(req.user._id);
if (!user) {
return error({ res, msg: strings.userNotFound, status: 404 });
}
// Delete Existing profile picture
deleteFileFromBucket(user.profileCover);
// Save the file path to the user document
user.profileCover = req.file.location;
// Save the updated user document
await user.save();
success({
res,
msg: strings.successUploadProfileCover,
data: {
profileCover: user.profileCover,
},
});
} catch (err) {
console.error(err);
error({ res, msg: strings.SERVER_ERR });
}
};