nodejs, multer, aws S3

Quick fixes:

  • remain same
const s3 = new AWS.S3({
    accessKeyId: process.env.AWS_ID,
    secretAccessKey: process.env.AWS_SECRET,
    region: process.env.AWS_REGION
});
  • the date and uuid variables both will initialize when node server start, it will never change until your node server restart, you just need to put it in to a function to return every time new file name,
  • here function returns filename except extension
function getFilename() {
    return new Date().toISOString() + '-' + uuidv4();
}
  • create function for transforms and pass same filename in both version from getFilename() function, add filename in metadata as well,
function getTransforms() {
    const fileName = getFilename();
    return {
        transforms: [
            {
                id: "full",
                key: (req, file, cb) => {
                    let fname = file.originalname.split(".")
                    cb(null, fname[0] + '-' + fileName + "_full.jpg")
                },
                transform: (req, file, cb) => cb(null, sharp().resize(2000).jpeg({ quality: 50 }))
            },
            {
                id: "thumb",
                key: (req, file, cb) => {
                    let fname = file.originalname.split(".")
                    cb(null, fname[0] + '-' + fileName + "_thumb.jpg")
                },
                transform: (req, file, cb) => cb(null, sharp().resize(100).jpeg({ quality: 30 }))
            }
        ],
        metadata: (req, file, cb) => {
            let fname = file.originalname.split(".");
            cb(null, { 
                fieldName: file.fieldname, 
                key: fname[0] + '-' + fileName + ".jpg"
            });
        }
    }
}
  • call getTransforms() function, that will return transforms and matadata properties
  • i am not sure aboutyour login to store filename in database,
  • get name from transfoems.metadata that we passed from metadata, this will return only _full name,
router.post("/", async (req, res) => {

    const multerS3Config = multerS3({
        s3: s3,
        bucket: process.env.AWS_BUCKET,
        shouldTransform: true,
        acl: 'public-read',
        contentType: multerS3.AUTO_CONTENT_TYPE,
        ...getTransforms()
    });

    const upload = multer({
        storage: multerS3Config,
        limits: { fieldSize: 25 * 1024 * 1024 }
    });

    upload.array("images", config.get("maxImageCount"))(req, res, async(error) => {
        const paths = await req.files.map((file) => ({
            images: file.transforms[0].metadata.key
        }));
        await Post.create({
            title: req.body.title,
            userId: req.body.userId,
            Post_Images: paths,
        }, {
            include: [Post_Image]
        })
    });
    
})

Basically the statement multer-s3 Streaming multer storage engine for AWS S3. is enough to differentiate both multer and multer-s3.

The code has not been tested, you can workaround and see what’s happen!

Leave a Comment