How to handle file upload in a Nodejs REST API project

It doesn’t matter if you are building a photosharing app like Instagram or a simple todo app — you might just find out that you need to upload a file — image, pdf, docx, etc. This post will walk you through 2 simple methods of handling file uploads in an Express Nodejs app.

popular upload interface

One thing I love about Nodejs is that it allows us to use modules and packages by other developers to do most of our tasks. Uploading file is no different, there are three file upload modules I love especially, Multer, Multiparty and Formidable. I will be using multer for this post.

Let's start a new express app using the generator. Create a directory in your preferred location, let's call it express-uploads. Next cd in the created folder and run

npx express-generator

After successfully running this, run npm i to install the dependencies

npm i

You can test your express app at this point by visiting localhost:3000 in your browser and you should see the default express-generator page saying, Express welcome to express.

Time to install multer, run the code

npm i multer --save 

Let's create a config folder in the root of the project and then create a multer.js file that will handle our multer configuration.

mkdir config && touch config/multer.js

In order to upload using multer, we will have to configure where on our server the file will be uploaded to — destination and the name of the file on our server. Open the multer.js file and write this

const multer  = require('multer');

As you can on line 1, we required our multer dependency, to make it available, next we instantiated multer to a constant storage where we specified the destination to be ‘public/uploads’

destination: (req, file, cb) => {

and also change the name of the file by concatenating the time it was uploaded to the original name, in this way users who have a file of the same name will not have issues when it is uploaded.

filename: (req, file, cb) => {

Next, we defined a single upload instance of the multer with the name of the upload field we are expecting — profile_pic in this case

multer.single('profile_pic');

We have also passed options to the multer singleUpload instance such as the max allowed file size — 1024 * 1024 (1MB). There are additional options such as filter for determining the type of file — pdf, jpeg, etc.

const singleUpload = multer({

Next, we simply export it as a module

module.exports = {

Now let’s head over to our routes and add the upload function. Let’s add this in the users route. Open routes/user.js and change it to this

var express = require('express');

Nothing much here except that we required our multerConfig, and I introduced the controller. You can create a controller by doing

mkdir controllers && touch controllers/users.js

Inside the controller will look like this

const multerConfig = require('../config/multer')
const multer = require('multer');

We have an uploadSingleFile function that calls the instance of the multerConfig we created earlier. We pass an anonymous function into it

multerConfig.singleUpload(req, res, function(err) {

and now have access to the uploaded file through multer via req.file.

if(req.file){
return res.json({
'msg': 'uploaded',
'file':req.file});
}

If you need to save to a db for example with sequelize, you can do

User.update(id:user,id, {profile_picture: req.file.path});

We can also use this to check for errors, by adding a new MulterError instance as seen. This means we have to require the multer dependency

if (err instanceof multer.MulterError) {

Before you are able to upload, you need to create the upload directory we specified earlier in the multer config. Now let us run the app and test our upload.

npm run start

In Postman, we will visit the Post route localhost:3000/users/single-picture-upload and click on ‘body’, choose ‘form-data’ and in the key enter ‘profile_pic’, hover over it and select file, click on “select files” and chose a file from your system and hit send. If all goes well you will see the response below

{

Here is a link to the repo with the source code

Web&Mobile Apps*Corporate Communication*Artificial Intelligence*Blockchain*Got extra support from a supernatural source you should know about