File uploading is very common in the world of web development. When a web client or browser uploads a file to a backend server, it is generally submitted through an HTTP form and encoded as multipart/form-data.
Here’s where Multer acts as a middleware for Express and Node.js that makes it easy to handle this multipart/form-data when the users upload files. In this tutorial, we will give you the complete steps to use the Multer library to upload file in Node.js.
What Is Multer?
Multer is a middleware used for express and Node.js to handle the file uploads. In our case, Multer acts as a middleware helper when uploading files which makes easy to handle the multipart/form-data when we try to upload files.
Setting Up A Node.js Application
We will use Node Express framework to listen to the server. Next, install other dependencies which are required for the application.
npm install express body-parser --save
Create a server.js file and initialize all the dependency node modules, then create an Express app and finally make sure that the server listens to the receiving request from the web client.
require('./config/config.js'); const express = require('express'); const bodyParser = require('body-parser'); const upload = require('./routes/upload'); const app = express(); app.use(bodyParser.json()); app.use('/upload', upload); const PORT = process.env.PORT || 3001; app.listen(PORT , function() { console.log('App is running!'); }); module.exports = app;
Using config.js & config.json, initialize our s3 credentials like below.
// Define Environment let env = process.env.NODE_ENV || 'development'; // Add Keys to Host if (env === 'development' || env === 'test') { let config = require('./config.json'); let envConfig = config[env]; Object.keys(envConfig).forEach((key) => { process.env[key] = envConfig[key]; }) }
config.json will look like below:
{ "development": { "AWS_ACCESSKEY":"AWS_ACCESSKEY", "AWS_SECRETKEY":"AWS_SECRETKEY", "AWS_REGION":"AWS_REGION", "AWS_BUCKET":"AWS_BUCKET", "AWS_DIRECTORY_PATH":"AWS_DIRECTORY_PATH/" }
Upload Files To Amazon s3:
Now we need to create an endpoint in the Express application to handle uploading. Next, add the upload.js file inside routes folder and add the following code:
const express = require('express'); const async = require('async'); const router = express.Router(); const service = require('../services/service'); router.post('/upload', function(req, res) { async.parallel([ function(callback) { service.uploadImage(req, res, 'attachment', callback); ], function(err, result){ if (err) { return res.status(422).send(err); } else { res.status(200).send(result[0]); }) });
Installing NPM Dependency Packages:
Use the below comment to install NPM dependency packages.
npm install aws-sdk multer multer-s3 mime-types --save
Create service.js file inside the service folder and add the following code to handle the single upload.
const aws = require('aws-sdk'); const multer = require('multer'); const multerS3 = require('multer-s3'); const mime = require('mime-types'); aws.config.update({ secretAccessKey: process.env.AWS_SECRETKEY, accessKeyId: process.env.AWS_ACCESSKEY, region: process.env.AWS_REGION }); const s3 = new aws.S3(); const fileFilter = (req, file, cb) => { cb(null, true); if (req.query.type === 'document') { if (file.mimetype === 'application/pdf' || file.mimetype === 'application/msword' || file.mimetype === 'text/plain' || file.mimetype === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') { cb(null, true); } else { cb(new Error('Invalid file type, only PDF, DOC, DOCX and TXT is allowed!'), false); } else { if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png') { cb(null, true); } else { cb(new Error('Invalid file type, only JPG, JPEG and PNG is allowed!'), false); } const upload = multer({ fileFilter, limits:{ files: 1, // allow only 1 file per request fileSize: 1024 * 1024 * 10 // 10 MB (max file size) }, storage: multerS3({ acl: 'public-read', s3, contentType: multerS3.AUTO_CONTENT_TYPE, bucket: process.env.AWS_BUCKET, metadata: function (req, file, cb) { cb(null, {fieldName: 'TESTING_METADATA'}); }, key: function (req, file, cb) { let path = ''; let filename = Date.now().toString()+'.'+mime.extension(file.mimetype); if (req.query.module) { let dir_path = process.env.AWS_DIRECTORY_PATH; dir_path = dir_path.substring(0, dir_path.indexOf("/")) + `/${req.query.module}/`; path = dir_path + filename; } else { path = process.env.AWS_DIRECTORY_PATH + filename; cb(null, path); }) }); module.exports = { uploadImage: function (req, res, key, callback) { const singleUpload = upload.single(key); singleUpload(req, res, function(err) { if (err) { callback({error: {title: 'File Upload Error', detail: err.message}}); } else { callback(null, {url: req.file.location, key: req.file.key}); }); };
Steps To Upload Files Into Amazon s3
- First, we are initializing AWS Object using AWS credentials.
- Next, validating file format with help of fileFilter using mime types node module
- We are going to use multer to handle file uploads and the multer used here will allow 3 parameters: one for validating file format, next one to handle file size an the third one is storage which is going to upload files to s3 using multer S3
To achieve the single upload, we are using the multer method as ‘upload.single’ and for multiple uploads, you can use upload.array.
Why We Should Use Multer s3 To Upload File
Actually, Multer buffering the multipart uploads file into the actual filesystem which is very difficult to scale. In order to overcome these difficulties, we need to stream the uploaded file. Now you know why we are preferring to use Multer S3 package. Multer S3 is used integration piece for existing code samples from the Multer’s storage engine documentation.
In the above snippet, we are using different parameters like acl, s3, key inside the Multer S3. For more details about this, please check here (https://www.npmjs.com/package/multer-s3)
Love to read more from the Node.js experts? Post us your favorite & user-centric topics here, we would love to work on the right topics you love that remains helpful for node programmers.
[contact-form-7 404 "Not Found"]