Node.js: uploading files to Amazon S3 in ExpressJS

In this article we will see how to upload files to Amazon S3 in ExpressJS using the multer, multer-s3 modules and the Amazon SDK.

We need to install first the required modules.

npm install multer multer-s3 aws-sdk --save

The first step is to configure the AWS-SDK module with our login credentials.

It is essential to remember that your S3 bucket must be public, at least for what concerns the read permissions.

'use strict';

const express = require('express');
const app = express();
const multer  = require('multer');
const multerS3 = require('multer-s3');
const AWS = require('aws-sdk');

const s3 = new AWS.S3({
    accessKeyId: 'access-key-id',
    secretAccessKey: 'secret-access-key'
});

At this point we need to connect the AWS object instance with multer using the multer-s3 module as a storage object.

'use strict';

const express = require('express');
const app = express();
const multer  = require('multer');
const multerS3 = require('multer-s3');
const AWS = require('aws-sdk');

const s3 = new AWS.S3({
    accessKeyId: 'access-key-id',
    secretAccessKey: 'secret-access-key'
});

const uploadS3 = multer({
  storage: multers3({
    s3: s3,
    acl: 'public-read',
    bucket: 'bucket-name',
    metadata: (req, file, cb) => {
      cb(null, {fieldName: file.fieldname})
    },
    key: (req, file, cb) => {
      cb(null, Date.now().toString() + '-' + file.originalname)
    }
  })
});

The metadata() method is used to send additional data about the file we are uploading to Amazon. key() manages the name of the file that will be used by Amazon. In this example we added a Unix timestamp as a prefix to the original file name in order to avoid possible overwriting of files with the same name. cb() is used by multer within each storage object as a callback function. The first parameter of this function can be an instance of Error if we want to raise an exception or null in the case of a normal operation with the files.

Now we can define our route in ExpressJS.

'use strict';

const express = require('express');
const app = express();
const multer  = require('multer');
const multerS3 = require('multer-s3');
const AWS = require('aws-sdk');

const s3 = new AWS.S3({
    accessKeyId: 'access-key-id',
    secretAccessKey: 'secret-access-key'
});

const uploadS3 = multer({
  storage: multers3({
    s3: s3,
    acl: 'public-read',
    bucket: 'bucket-name',
    metadata: (req, file, cb) => {
      cb(null, {fieldName: file.fieldname})
    },
    key: (req, file, cb) => {
      cb(null, Date.now().toString() + '-' + file.originalname)
    }
  })
});

app.post('/upload', uploadS3.single('file'),(req, res) => {
  console.log(req.file);
});

app.listen(process.env.PORT || 3000);

file is the value of the name attribute of the input field of type file sent from the HTML form. Once uploaded, req.file will contain all the information about the uploaded file returned by Amazon. We can use this object to perform further operations, such as saving the final URL of the image on Amazon S3 to a database.

Back to top