Cloudinary Files / Images CRUD operations with Nodejs, Express, Multer
Tags: node, mongodb, cloudinary
Published: 2020-10-07 15:30:45

In this article we will upload, retrieve, update and delete images from Cloudinary. For that, we will use nodejs, express, multer, cloudinary and also mongoDB as our database.

If you prefer watching video tutorial then watch this:

{% youtube LWB1s6P0wgE %}

or you may continue reading. First of all create project directory, open this directory in code editor. Now we will initialize **package.json** file. Open your terminal and run
`npm init -y`

After that we will install a few dependencies.
`npm install express mongoose cloudinary multer dotenv`

Optionally, I will also install nodemon as dev dependency to constantly watch server.
`npm install -D nodemon`

Now within **package.json** inside "scripts", add
`"server": "nodemon index"`

Now we will setup basic express server. Create **index.js** file and paste the following code.
```
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
dotenv.config(); 

// Connect DB
mongoose
  .connect(process.env.MONGO_URI, {
    useCreateIndex: true,
    useNewUrlParser: true,
    useFindAndModify: false,
    useUnifiedTopology: true,
  })
  .then(() => console.log("mongoDB is connected"))
  .catch((err) => console.log(err)); 

// Middleware
app.use(express.json());

app.listen(5000, () => console.log("Server is running"));
```

Create .env file and add
`MONGO_URI=path-to-your-mongodb`

Open terminal and type `npm run server` to see if everything is working fine.

Lets create a folder at root level **models** and inside models create a file **user.js** and paste the following code
```
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
  name: {
    type: String,
  },
  avatar: {
    type: String,
  },
  cloudinary_id: {
    type: String,
  },
});
module.exports = mongoose.model("User", userSchema);
```
Here we have defined three fields, name, avatar and cloudinary_id. We will need cloudinary_id when we will send put / delete request later.

Go to [Cloudinary website](https://cloudinary.com) and register / login. You will be redirected to your dashboard where under **Account Details** you will find your **Cloud Name**, **API Key** and **API Secret**. Copy their values and inside **.env** file create 3 variables to store those values
```
CLOUD_NAME=YOUR-CLOUD-NAME
API_KEY=YOUR-API-KEY
API_SECRET=YOUR-API-SECRET
```

Now create a folder at root level **utils** and create 2 files inside this folder, **cloudinary.js** and **multer.js**. Here we will configure cloudinary and multer. Inside **cloudinary.js** paste the following code
```
const cloudinary = require("cloudinary").v2;
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
}); 
module.exports = cloudinary;
```
Inside **multer.js** paste the following code.
```
const multer = require("multer");
const path = require("path"); 
// Multer config
module.exports = multer({
  storage: multer.diskStorage({}),
  fileFilter: (req, file, cb) => {
    let ext = path.extname(file.originalname);
      if (ext !== ".jpg" && ext !== ".jpeg" && ext !== ".png") {
      cb(new Error("File type is not supported"), false);
      return;
    }
    cb(null, true);
  },
});
```
Here we have required multer and nodejs core module path. We required path to extract file extension in order to filter files we want to allow.

Go to **index.js** and before listening to server, add
```
// Route
app.use('/user', require('./routes/user'))
```

Let's create a folder at root level **routes** and inside routes create file **user.js**. Now we will send a post request to upload image to cloudinary. Inside **user.js** file paste the following
```
const router = require("express").Router();
const cloudinary = require("../utils/cloudinary");
const upload = require("../utils/multer");
const User = require("../model/user"); 
router.post("/", upload.single("image"), async (req, res) => {
  try {
    // Upload image to cloudinary
    const result = await cloudinary.uploader.upload(req.file.path);
     // Create new user
    let user = new User({
      name: req.body.name,
      avatar: result.secure_url,
      cloudinary_id: result.public_id,
    });
    // Save user
    await user.save();
    res.json(user);
  } catch (err) {
    console.log(err);
  }}); 
 module.exports = router;
```
Here we required express router, from utils folder cloudinary and multer and User model. We are uploading single image so right after router url, we have specified upload.single('image').

We used **cloudinary.uploader.upload** and pass the file path to upload method to get the image. We stored the response we got back from cloudinary into result variable. It will be an object and we will use two properties **secure_url** and **public_id**.

After the image is uploaded, we created new instance of user. name will be provided in req.body, avatar and cloudinary_id values will be result.secure_url and result.public_id respectively.

Now go to **postman** make a POST request to http://localhost:5000/user provide **name** and **image** in form-data and hit SEND. Navigate to "Media Library" in your cloudinary account you will find the image you just uploaded.

Let's make a GET request, go to **user.js** and paste the following
```
router.get("/", async (req, res) => {
  try {
    let user = await User.find();
    res.json(user);
  } catch (err) {
    console.log(err);
  }});
```
DELETE request
```
router.delete("/:id", async (req, res) => {
  try {
    // Find user by id
    let user = await User.findById(req.params.id);
    // Delete image from cloudinary
    await cloudinary.uploader.destroy(user.cloudinary_id);
    // Delete user from db
    await user.remove();
    res.json(user);
  } catch (err) {
    console.log(err);
  }});
```
First find user by id, after that we are deleting file from cloudinary. **destroy** method takes **public_id** as argument, we have stored public_id as cloudinary_id into our DB

PUT request
```
router.put("/:id", upload.single("image"), async (req, res) => {
  try {
    let user = await User.findById(req.params.id);
    // Delete image from cloudinary
    await cloudinary.uploader.destroy(user.cloudinary_id);
    // Upload image to cloudinary
    const result = await cloudinary.uploader.upload(req.file.path);
    const data = {
      name: req.body.name || user.name,
      avatar: result.secure_url || user.avatar,
      cloudinary_id: result.public_id || user.cloudinary_id,
    };
    user = await User.findByIdAndUpdate(req.params.id, data, {
 new: true
 });
    res.json(user);
  } catch (err) {
    console.log(err);
  }});
```
First find user by id, then delete the existing image from cloudinary. After that upload the new image to cloudinary and update the data with the updated secure_url and public_id into our database as avatar and cloudinary_id

So thats how we can perform CRUD operations on cloudinary with nodejs multer and cloudinary.

[Github repo](https://github.com/itsmefarhan/nodejs-cloudinary-crud-operations)