IMAGE/FILE UPLOAD IN NODE.JS WITH CLOUDINARY
Tags: node, javascript, webdev, programming
Published: 2023-05-07 18:12:37

Image and file upload is a very important concept in backend development especially if you are building a very large application.

> You do not want to keep images and files on the server to avoid slowing down of the server.

So storing this files in an external source is advised to optimize performance of the server and application.

`Cloudinary` is my favorite library for images and file upload, and quickly I am going to get you started on how to start storing images and files on `cloudinary`

_`Cloudinary` enables developers to efficiently manage, transform, optimize, and deliver images and videos through multiple CDNs._.

### REQUIREMENTS:
*Knowledge of node.js, express.js and REST APIs.*

## STEP 1
**Initialize your project and install needed dependencies**

```js
npm init
npm install express body-parser dotenv cloudinary express-fileupload nodemon
```

- express: create an express app

- body-parser: process data sent in an HTTP request body

- express-fileupload: makes your uploaded files/images accessible on the `req.files` object

- dotenv: to import environmental variables

- Cloudinary: images/file storage library

- nodemon: watch files

## STEP 2
**Create an app.js file, inside it import the installed dependencies and create an express app.**

_Note: create a `.env` file in the root of your folder and store your environment variables there._

```js
// import dependencies
const express = require("express");
const bodyParser = require("body-parser");
const fileUpload = require("express-fileupload");
const dotenv = require("dotenv").config();
const cloudinary = require("cloudinary").v2;

// create express app
const app = express()

app.use(bodyParser.json());
app.use(express.json());
app.use(fileUpload({ useTempFiles: true }));

const port = process.env.PORT || 8000;

app.listen(port, () => {
  console.log(`server running at port ${port}`);
});
```

## STEP 3 
**Create an account with cloudinary [here](https://cloudinary.com/users/register_free) and store your API keys and details _(CLOUD_NAME, API_KEY and API_SECRET)_ inside your `.env` file**

## STEP 4
**Configure cloudinary in your app.js file**

```js
const express = require("express");
const bodyParser = require("body-parser");
const fileUpload = require("express-fileupload");
const dotenv = require("dotenv").config();
const cloudinary = require("cloudinary").v2;

const app = express()

// configure cloudinary
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.CLOUD_API_KEY,
  api_secret: process.env.CLOUD_API_SECRET,
});

app.use(bodyParser.json());
app.use(express.json());
app.use(fileUpload({ useTempFiles: true }));

const port = process.env.PORT || 8000;

app.listen(port, () => {
  console.log(`server running at port ${port}`);
});
```
_NOTE: Add this script to your package.json file and `npm start`_

```js
 "scripts": {
    "start": "nodemon app.js"
  },
```

## STEP 5
**Create a `file-controller.js` file and a `file-router.js` file.
Create an express router inside the `file-router.js` file and export to `app.js` file**

```js
const express = require("express");
const fileController = require("./file-controller");

// create a router
const router = express.Router();

// create a post router for file upload
router.post("/", fileController.fileUpload);

// export to app.js file
module.exports = router;
```

## STEP 6
**Register the file-upload route inside the app.js file**

```js
const express = require("express");
const bodyParser = require("body-parser");
const fileUpload = require("express-fileupload");
const dotenv = require("dotenv").config();
const cloudinary = require("cloudinary").v2;

const app = express();

cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.CLOUD_API_KEY,
  api_secret: process.env.CLOUD_API_SECRET,
});

const fileRouter = require("./file-router");

app.use(bodyParser.json());
app.use(express.json());
app.use(fileUpload({ useTempFiles: true }));

// register route in app.js file
app.use("/api/file-upload", fileRouter);

const port = process.env.PORT || 8000;

app.listen(port, () => {
  console.log(`server running at port ${port}`);
});
```

## STEP 7:
**Inside the file-controller.js file, import cloudinary and let us start writing the file-upload logic**

_Don't forget the express-fileupload dependency we installed will make the uploaded image available on the `req.files` object_

> So let us extract it

```js
exports.fileUpload = async (req, res) => {
  const uploadedImage = req.files.image;
};
```

## STEP 8:
**Parse the uploaded image/file to cloudinary;**

_Note: Create a folder inside your cloudinary media library and pass the name of the folder as an arguement like this_

```js
const cloudinary = require("cloudinary").v2;

exports.fileUpload = async (req, res) => {
  const uploadedImage = req.files.image;

  const result = await 
    cloudinary.uploader.upload(uploadedImage.tempFilePath, {
    use_filename: true,
    folder: "your_folder_name_here",
  });
};
```

## STEP 9:
 
**The result object contains a secure_url parameter which is a url to the image you uploaded on cloudinary,** 

**So pass this url to the frontend to display the uploaded image or paste in your browser to view the image**

```js
const cloudinary = require("cloudinary").v2;

exports.fileUpload = async (req, res) => {
  const uploadedImage = req.files.image;

  const result = await 
    cloudinary.uploader.upload(uploadedImage.tempFilePath, {
    use_filename: true,
    folder: "your_folder_name_here",
  });

  return res.status(201).json({
    src: result.secure_url,
  });
};
```

## FINAL STEP:
**Call this route `/api/file-upload` and upload your image/files.**

Checkout my source codes [here](https://github.com/MrCandie/image-file-upload)