Introduction
In this article we will be learning how to create a RESTFUL API endpoint to enable us upload a file to the backend/ server.
What is Multer
From the documentation, multer is defined as a node.js middleware whose primary purpose is for uploading files to the backend. This middleware as any other middleware helps to observe any incoming request and helps us manage any file attached to the request. When a requestis made from the frontend, we must ensure that Content-Type
is set to multipart/form-data
in the request headers
when using RESTFUL API. This must be done for upload to be successful.
Let's get to business
Create your express server
This section involves setting up your server with express, if you're familiar with this process and would want to skip to using multer
then you can skip this section. First, lets create a js
file in a folder and name it app.js
. Open your app.js
file in your code editor and follow the steps below;
- Goto your terminal to initialize your
npm
for the project, type the following code;
npm init -y
- install the following dependencies for this project;
npm install express multer
npm install nodemon -D
- Add the following code to your
app.js
file;
// imports the express module into our project
const express = require('express')
// imports the multer module into our project
const multer = require('multer')
// creates an instance of our app server
const app = express()
// set our server to listen on port 5000
app.listen(5000, ()=> console.log('server is running on port 5000'))
- Goto to your
package.json
file and add a script to enable nodemon restart the server automatically anytime a change is done.
- Finally on the terminal run this script,
npm start
// server is running on port 5000
Now our server is live and we can begin to code the api endpoints we want to handle.
Using Multer middleware
Multer accepts an options config with contains 3 important properties used to save, filter the type of file you want to accept and/or limit the size of file that can be uploaded to the server. The multer function returns a middleware object that can be passed into our endpoint. See code below;
const upload = multer();
multer returns a middleware object which we assign to upload
variable. Now we should pass a config option to define how we want how our file to be handled. These important properties include;
storage/dist
limits
filefilter
Storage/dist
The storage/dist propety tells multer where to store the file. If you want more control over your uploads, you'll want to use the storage
option instead of dest
. Multer ships with storage engines DiskStorage
and MemoryStorage
. DiskStorage
engine can help us to also customise how we want our file to be saved. Let's add storage to our multer;
const MIME_TYPE = {
"image/png": "png",
"image/jpg": "jpg",
"image/jpeg": "jpeg",
};
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./images"); // Storage location
},
filename: function (req, file, cb) {
cb(
null,
file.fieldname + "-" + Date.now() + "." + MIME_TYPE[file.mimetype]
); // return a unique file name for every file
},
});
const upload = multer({storage:storage}).single('profile_img');
There are two options available, destination
and filename
. They are both functions that determine where the file should be stored. We will be storing our file in a folder callled images
, make sure to create a folder in your root directory called images
.
filename
is a function used to create a customised filename before saving to our backend.
limits
This is used to set limits to the file size to accept. Here, we will be setting the limit to file size;
const upload = multer({
storage:storage
limits: {
fileSize: 1000000,
}, // this set the maximum file that can be uploaded to 1mb
}).single('profile_img');
filefilter This sets to a function that is used to filter the type of files that should be accepted. This can help to protect against uploading random files and hackers who may want to upload a corrupt file to your server.
const MIME_TYPE = {
"image/png": "png",
"image/jpg": "jpg",
"image/jpeg": "jpeg",
}; // store the different image formats we want to accept
const upload = multer({
storage:storage
limits: {
fileSize: 1000000,
}, // this set the maximum file that can be uploaded to 1mb
fileFilter: (req, file, cb) => {
const uploadFile = !!MIME_TYPE[file.mimetype]; //check that this file type is acceptable
if (!uploadFile) {
return cb(new Error("Error with wrong file")); // return an error if file type is not acceptable
}
cb(null, true); // allow the file to saved if file type is acceptable
}
}).single('profile_img');
Using the middleware object in our route
app.post("/upload", (req, res, next) => {
console.log("upload was called");
upload(req, res, (err) => {
// check if there is an error trying to upload
// return an error if error occurred
// else file upload was successful
if (err instanceof multer.MulterError) {
// handle error that is associated with multer
res.status(500).json({ message: err.message });
} else if (err) {
// handle any other form of error
res.status(500).json({ message: err.message });
} else {
// file upload was successful
// continue with other logic for this endpoint
res.json({ message: "upload successful!" });
}
});
});
Finally
We have successfully, uploaded a file to the backend server. I hope learnt a lot. I will be happy to answer questions in the comments. Don't forget to like and share if you enjoyed and learnt something new from the post.