DEV Community

NJOKU SAMSON EBERE
NJOKU SAMSON EBERE

Posted on • Updated on

Nodejs Code Structure Optimization With Express Routing

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. It is going to be a very simple tutorial.

Let's Go There

Getting Started

If you are coming from the last tutorial, please skip to cleaning my code.

As a prerequisite, I suggest you start from the previous tutorial.

However, you can get the starter code for this tutorial here.

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

Let's party

Cleaning My Code

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

mk dir routes

Enter fullscreen mode Exit fullscreen mode
  • In the routes folder, create a file with the name: routes.js.

For windows


echo . > routes.js

Enter fullscreen mode Exit fullscreen mode

For Mac


touch routes.js

Enter fullscreen mode Exit fullscreen mode
  • Empty the routes.js file if any thing is there and enter the following code

const express = require('express');

const router = express.Router();



module.exports = router;

Enter fullscreen mode Exit fullscreen mode
  • Add the following codes above the last line

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,
});

Enter fullscreen mode Exit fullscreen mode
  • Back in the App.js file, delete the following code

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,
});

Enter fullscreen mode Exit fullscreen mode
  • Move all the APIs to routes.js

  • Change all occurence of app to router carefully

  • My routes.js file now looks like this

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


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

Enter fullscreen mode Exit fullscreen mode
  • Now register the routes like so:

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

Enter fullscreen mode Exit fullscreen mode
  • This is my app.js file at the moment

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;

Enter fullscreen mode Exit fullscreen mode

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

retrieve-image
retrieve image

update-image
update image

delete-image
delete image

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

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

(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,
      });
    });
}

Enter fullscreen mode Exit fullscreen mode

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


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,
        });
      });
  }

Enter fullscreen mode Exit fullscreen mode

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


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,
        });
      });
  }

Enter fullscreen mode Exit fullscreen mode

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


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

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

Enter fullscreen mode Exit fullscreen mode

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

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

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

Yayeh!!! We have a world class code structure now compared to the last tutorial.

Congratulations on you success so far!!!

Conclusion

We have made it from a very far beginning. Starting from setting up a simple, 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

GitHub logo EBEREGIT / server-tutorial

This is a tutorial was to teach how to create a simple, secure and robust nodejs server but we have expanded our scope to cloudinary and postgres

Server-tutorial

This is a tutorial was to teach how to create a simple, secure and robust nodejs server but we have expanded our scope to cloudinary and postgres

Full details on how to build out this server is found here.

Full details on how to upload images to cloudinary using nodejs is found here.

Full details on how to persist and retrieve images to cloudinary using nodejs and postgres is found here.

Full details on how to delete and update images to cloudinary using nodejs and postgres is found here.

Full details on Nodejs Code Structure Optimization With Express Routing is found here.

Dependences

SETTING UP

  • Fork this repository
  • Clone the repositury to your machine
  • Open up a terminal
  • Navigate into the project directory
  • Run npm install to install all needed dependencies
  • Run nodemon index to spin…

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

The next article 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 | LinkedIn | Github

Thank You For Your Time.

Top comments (0)