Search code examples
node.jsexpressmulteraws-sdk-nodejs

How do I dynamically specify a file path I would like to upload to in my s3 bucket using multer


So, I'm quite new to Nodejs and I'm trying to implement a API to upload file to an s3 bucket. But, I'd like to specify the file path to upload each file to as an optional parameter. What's the simplest way to achieve this? Here is the original code for uploading a file

require("dotenv/config");
const express = require("express");
const multer = require("multer")
const AWS = require("aws-sdk")

const app = express();
const port = process.env.PORT || 3000;

const s3 = new AWS.S3({
    accessKeyId: process.env.AWS_ID,
    secretAccessKey: process.env.AWS_SECRET,
    region: process.env.AWS_REGION
})

const storage = multer.memoryStorage({
    destination: (req, file, callback) => {
        callback(null, "")
    }
})

const upload = multer({storage}).single("file");

app.post("/upload", upload, (req, res) => {
    let myFile = req.file.originalname

    const params = {
        Bucket: process.env.AWS_BUCKET_NAME,
        Key: myFile,
        Body: req.file.buffer,
        
    }

    s3.upload(params, (error, data) => {
        if(error) {
            res.status(500).send(error)        
        }

        res.status(200).send(data)

    })
});


app.listen(port, () => {
    console.log(`Server is up at ${port}`)
});



Solution

  • If you are trying to upload files to a folder, AWS s3 simulates this by adding prefixes. You can change the Key parameter by adding the folder name.

    app.post("/upload/:directory", upload, (req, res) => {
        let myFile = req.file.originalname
        let path = req.params.directory
    
        const params = {
            Bucket: process.env.AWS_BUCKET_NAME,
            Key: `${path}/${myFile}`,
            Body: req.file.buffer,
            
        }
    
        s3.upload(params, (error, data) => {
            if(error) {
                res.status(500).send(error)        
            }
    
            res.status(200).send(data)
    
        })
    });