UPLOADING IMAGE TO CLOUDINARY USING NODEJS
Hello world!! This is a tutorial on how to upload your images being posted from the client side to cloudinary using a Nodejs backend server.
Introduction
In this article, we are going to create a RESTful API that take a post request, and our aim will be to store the incoming image to cloudinary and use mongodb as our database.
We will be using the Model View Controller (MVC) approach and also will be using express.js which is a Nodejs framework that will help us setup the routes easily.
This article will span through four steps:
- Step One: Creating a cloudinary account for our image.
- Step Two: Creating a sample project, initialization and Installation of all Dependencies for the project
- Step Three: Setup Server, App.js, multer, and cloudinaryConfig.
- Step Four: Create Models, Controllers and Route.
Prerequisite:
It is required for the sake of this tutorial that you have the following installed globally in your machine:
- Node: You can check out this node doc to install node.
- Mongo: check the documentation here
- MongoAtlas
- nodemon: Check the documentation here.
Hence, before you dive into this tutorial, i recommend that you should have a knowledge in Nodejs and MongoDB.
Step One:
Creating a Cloudinary account.
Cloudinary is the market leader in providing a comprehensive cloud-based image and video management platform. Cloudinary is being used by hundreds of thousands of users around the world, from small startups to large enterprises. Check out Cloudinary about page to know more.
If you already have an account with cloudinary, you can skip this step else, let us create our cloudinary account.
Visit Cloudinary fill all the required details and also remember to put a working email address, and create account. very easy!
Yay! You’ve created an account with cloudinary, let us get our hands dirty with some codes.
Step Two:
Create a project, initialization and Installation of all dependencies for the project:
Create a folder, give it any name of your choice. I’ll call mine image-app for the purpose of this tutorial, then open a command prompt and navigate to the working folder using:
Note that you can also create the folder directly from the command prompt and initialize the project with npm init which would create a package.json file for our project.
$ mkdir image-app
$ cd image-app
$ npm init
when you’re done it will look like the image below.
After creating package.json file, the next thing will be to install express. Therefore inside the image-app working folder, lets install some dependencies which are express, multer , border-parser and mongoose.
To know more about Expressjs check out the documentation here
$ npm install express multer body-parser mongoose
Once you’ve successfully installed express, multer, mongoose and body-parser, then go ahead to install cloudinary for the image storage.
$ npm install cloudinary
Step Three:
Setup Server, App.js, multer, and cloudinaryConfig.
Server.js:
In your preferred code editor, create a file and you can name it server.js. Inside the file, write the following code to create a server.
Notice that we required app inside the server.js file, this is because we will be accessing the functions inside the app.js file such express.js.
APP.JS:
App.js will contains express.js, which allows us to set up middlewares to respond to HTTP Requests and also defines a routing table which is used to perform different actions based on HTTP Methods and URL.
Hence let’s create another file, i’ll call mine app.js, and inside the file write the following code and i will explain.
var express = require('express');var bodyParser = require('body-parser');var path = require('path');// THIS WILL ALLOW US TO SET UP MIDDLEWARES TO RESPOND TO HTTP REQUEST.var app = express();// HERE WE WILL LET OUR APP TO GET ACCESS TO THE STATIC FOLDERS LIKE CSS, IMAGES.app.use(express.static(path.join(__dirname, 'public')));app.use('/uploads', express.static('uploads'));app.use(bodyParser.urlencoded({extended: false}));app.use(bodyParser.json());// HANDLING CORS ERRORSapp.use((req, res, next) =>{res.header('Access-Control-Allow-Origin', '*');res.header('Access-Control-Allow-Headers', '*');if(req.method === 'OPTIONS'){res.headers('Access-Control-Allow-Methods', 'POST, PUT, GET, DELETE');return res.status(200).json({})}next();});//HANDLE ERRORapp.use((req, res, next) => {const error = new Error('NOT FOUND')error.status = 404next(error)})app.use((error, req, res, next) => {res.status(error.status || 500)res.json({error: {message: error.message}})})// DO NOT FORGET TO EXPORT THE FILEmodule.exports = app
Let us briefly explain the code above.
We required express which we explained above.
Bodyparser which is a node middleware for handling JSON, Raw, text and url encoded form data. The path there accounts for the project folder/directory we are working with.
Then if you notice inside the code we enabled CORS (Cross-Origin Resource Sharing) which is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin.
visit developer mozilla for more information.
Finally we handled error to avoid our app crashing when we receive an unwanted request.
Therefore, Once you’ve setup your server.js and app.js file correctly, then run:
nodemon server.js
Note: install nodemon if you haven’t, check out nodemon here.
you’ll see this —
Yay! now the server is running successfully, let us configure cloudinary in our project.
Cloudinary Config:
Create a file and you can name it cloudinaryConfig.js, then visit Cloudinary website and login to your account, go to your dashboard and copy your cloud name, api key and api secret. It will look like this code below:
Inside the cloudinaryConfig.js file, paste the code below:
const cloudinary = require('cloudinary');cloudinary.config({cloud_name: 'code-freak',api_key: '***45437*******',api_secret: 'it's a secret api ofcourse'});
Also inside the cloudinaryConfig file, add the cloudinary API which will help us upload images and get response.
exports.uploads = (file) =>{return new Promise(resolve => {cloudinary.uploader.upload(file, (result) =>{resolve({url: result.url, id: result.public_id})}, {resource_type: "auto"})})}
In the above code, the result.url is the url that will be returned for accessing the image.
public_id: This is the unique identifier in the form of a public ID, which is a URL-safe string that is used to reference the uploaded resource.
Multer:
The next step is to configure multer which is a node.js middleware for handling multipart/form-data
, which is primarily used for uploading files.
Hence create a file you can name it multerConfig.js and set it up like this:
var multer = require('multer');//multer.diskStorage() creates a storage space for storing files.var storage = multer.diskStorage({destination:function(req, file,cb){if(file.mimetype === 'image/jpeg' || file.mimetype === 'image/png'){cb(null, './files/images/');}else{cb({message: 'this file is neither a video or image file'}, false)}},filename: function(req, file, cb){cb(null, file.originalname);}})var upload = multer({storage:storage});module.exports = upload;
Let’s explain what is happening in the code above.
Destination: This indicates where you want to save your files, we used normal function and used the if statement to check if the file type is jpeg or png.
Filename: This indicates how you want your files named.
Step Four:
Create Models, Controllers and Route
Model:
This is simply the structure of data, the format with which it is stored. Basically it is the database part of the application, and for the sake of this article we will use mongoDB.
Therefore mongoose was required and we used it to setup the schema.
The model for this project looks like this:
var mongoose = require('mongoose');
var imageUpload = mongoose.Schema({imageName: {
type: String,
required: true
},cloudImage: {
type: String,
required: true
},imageId: {
type: String
},post_date: {
type: Date,
default: Date.now
}})module.exports = mongoose.model('imageUpload', imageUpload)
Controllers:
This is were we have to control the request coming from the client and create appropriate response which is sent back to the client. In a nut shell, is a request-response handler.
The code looks like this:
//IMPORT THE MODEL WE CREATED EARLIER
var imageModel = require('./models');//IMPORT CLOUDINARY CONFIG HERE
var cloud = require('./cloudinaryConfig');exports.createApp = (req, res) => {
try{
var imageDetails = {
imageName: req.body.imageName,}
//USING MONGO METHOD TO FINE IF IMAGE-NAME EXIST IN THE DBimageModel.find({imageName: imageDetails.imageName}, (err, callback) => {//CHECKING IF ERROR OCCURRED
if (err) {res.json({
err: err,
message: 'there was a problem uploading image'
})} else if(callback.length >= 1 ) {res.json({