Nodejs Code Structure Optimization With Express Routing
Tags: routing, node, optimization, express
Published: 2020-05-19 08:53:55

Express Routing enables us to make our nodejs code more optimized or give it a more modular structure by seperating the business logic from the controllers. We want to use that to clean up our code from the [last tutorial](https://dev.to/ebereplenty/cloudinary-and-postgresql-deleting-and-updating-images-using-nodejs-l8d). It is going to be a very simple tutorial.

![Let's Go There](https://media.giphy.com/media/3ohhwyXhrNXmL831XG/giphy.gif)

## Getting Started
If you are coming from the [last tutorial](https://dev.to/ebereplenty/cloudinary-and-postgresql-deleting-and-updating-images-using-nodejs-l8d), please skip to [cleaning my code](#1).

As a prerequisite, I suggest you start from the [previous tutorial](https://dev.to/ebereplenty/cloudinary-and-postgresql-deleting-and-updating-images-using-nodejs-l8d).

However, you can get the starter code for this tutorial [here](https://github.com/EBEREGIT/server-tutorial).

Now that we are all on the same page, let's get to the party 

![Let's party](https://media.giphy.com/media/3IUZqk1EggpftgrBi1/giphy.gif)

<a name="1"></a>
## Cleaning My Code

* We begin by creating a new folder with the name: ``routes`` in the root directory

```javascript

mk dir routes

```

* In the routes folder, create a file with the name: ``routes.js``.

For windows
```javascript

echo . > routes.js

```

For Mac
```javascript

touch routes.js

```

* Empty the ``routes.js`` file if any thing is there and enter the following code

```javascript

const express = require('express');

const router = express.Router();



module.exports = router;

```

* Add the following codes above the last line

```javascript

const cloudinary = require("cloudinary").v2;
require("dotenv").config();
const db = require("../services/dbConnect.js");

// cloudinary configuration
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
});

```
* Back in the App.js file, delete the following code

```javascript

const cloudinary = require("cloudinary").v2;
require("dotenv").config();
const db = require("./services/dbConnect.js");

// cloudinary configuration
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
});

```

* Move all the APIs to ``routes.js``

* Change all occurence of ``app`` to ``router`` carefully

* My ``routes.js`` file now looks like [this](https://github.com/EBEREGIT/server-tutorial/blob/routing/routes/routes.js)


* Back in the ``app.js`` file, import the ``routes.js`` file like so:

```javascript

// import the routes file
const routes = require("./routes/routes")

```

* Now register the routes like so:

```javascript

// register the routes 
app.use('/', routes);

```

* This is my ``app.js`` file at the moment

```javascript

const express = require("express");
const app = express();

// import the routes file
const routes = require("./routes/routes")

// body parser configuration
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// register the routes 
app.use('/', routes);

module.exports = app;

```

It's time to test and see if our routes are still working like before.

Make sure yours is working like mine below:

**persist-image**
![persist image](https://dev-to-uploads.s3.amazonaws.com/i/r2uz54xix054li4lgw6i.JPG)

**retrieve-image**
![retrieve image](https://dev-to-uploads.s3.amazonaws.com/i/o44a1dnfgvz3r9sv3a1j.JPG)

**update-image**
![update image](https://dev-to-uploads.s3.amazonaws.com/i/6t9k5m079rwx4p6ouax3.JPG)

**delete-image**
![delete image](https://dev-to-uploads.s3.amazonaws.com/i/nkkydplioi68la4eynhp.JPG)

Wow!!! We have been able to separate our routes from our ``app.js`` file. 

Even though our ``routes.js`` file is still lengthy, we have a good basis to separate our business logic from our controllers. The time has arrived to do just that.


## Separating each API to a different file
* Begin by creating a new folder in the ``routes`` folder and name it ``controllers``.

* In the controllers folder, create 5 files and name them after the 5 endpoints.

Our folder and files should be structured as follows:

![folder and files structure](https://dev-to-uploads.s3.amazonaws.com/i/dmren2r2w2801lf28wjy.JPG)

* Back in the routes.js file, let's work on the ``image-upload`` API. Cut the following code 

```javascript

(request, response) => {
  // collected image from a user
  const data = {
    image: request.body.image,
  };

  // upload image here
  cloudinary.uploader
    .upload(data.image)
    .then((result) => {
      response.status(200).send({
        message: "success",
        result,
      });
    })
    .catch((error) => {
      response.status(500).send({
        message: "failure",
        error,
      });
    });
}

```
In the ``imageUpload`` file, equate the code you already cut from the ``image-upload`` API to ``exports.imageUpload`` like so:

```javascript

exports.imageUpload = (request, response) => {
    // collected image from a user
    const data = {
      image: request.body.image,
    };
  
    // upload image here
    cloudinary.uploader
      .upload(data.image)
      .then((result) => {
        response.status(200).send({
          message: "success",
          result,
        });
      })
      .catch((error) => {
        response.status(500).send({
          message: "failure",
          error,
        });
      });
  }

```

Now let's import what is necessary for this code to work. So this is my ``imageUpload`` file right now

```javascript

const cloudinary = require("cloudinary").v2;
require("dotenv").config();

// cloudinary configuration
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
});

exports.imageUpload = (request, response) => {
    // collected image from a user
    const data = {
      image: request.body.image,
    };
  
    // upload image here
    cloudinary.uploader
      .upload(data.image)
      .then((result) => {
        response.status(200).send({
          message: "success",
          result,
        });
      })
      .catch((error) => {
        response.status(500).send({
          message: "failure",
          error,
        });
      });
  }

```

Let's import and register the ``imageUpload`` API  in the ``routes.js`` file like so:

```javascript

const imageUpload = require("./controllers/imageUpload");

// image upload API
router.post("image-upload", imageUpload.imageUpload);

```
Now we have this line of code pointing to the ``imageUpload`` API in the ``imageUpload.js`` file from the ``routes.js`` file. 

How awesome! Our code is more readable.

Make sure to test the API to be sure it's working properly. Mine works perfectly. See image below:

![image upload test result](https://dev-to-uploads.s3.amazonaws.com/i/t456z1fz1537nja0huyr.JPG)

Now, it's your turn!!!

Apply what you have learnt to the other APIs. Let's see what you have got.

I will be waiting on the other side 

![See You Soon](https://media.giphy.com/media/l1J3CbFgn5o7DGRuE/giphy.gif)

If you are here, then I believe you have done yours and it's working perfectly or atleast, you already gave it your best shot. Kudos!!!

Checkout mine [here](https://github.com/EBEREGIT/server-tutorial/tree/controller-setup/routes)

Yayeh!!! We have a world class code structure now compared to the [last tutorial](https://dev.to/ebereplenty/cloudinary-and-postgresql-deleting-and-updating-images-using-nodejs-l8d).

Congratulations on you success so far!!!

### Conclusion
We have made it from a very far beginning. [Starting from setting up a simple](https://dev.to/ebereplenty/setting-up-a-simple-secure-and-robust-node-js-server-10n0), secure and robust server to hear now has been a huge progress.

This tutorial is a wrap up of the CRUD App which actually ended in the previous tutorial but optimized in this tutorial.

All codes can be found [here](https://github.com/EBEREGIT/server-tutorial/tree/controller-setup)

{% github EBEREGIT/server-tutorial %}

We can now say that we are completely done with the back-end of this APP. How about hosting?

The [next article](https://dev.to/ebereplenty/pushing-to-github-and-hosting-on-heroku-for-free-kch) will address that

If you have questions, comments or suggestions, please drop them in the comment section.

You can also follow and message me on social media platforms. 

**[Twitter](https://twitter.com/eberetwit) | [LinkedIn](https://www.linkedin.com/in/samson-ebere-njoku-profile/) | [Github](https://github.com/EBEREGIT)**

Thank You For Your Time.