A simple CRUD using min-route package

In this blog  we’ll create a simple CRUD application using the min-route library. 

min-route: A simple and lightweight library to manage server side routes. It uses only 4 routes for the whole project. It is based on Rest API and it is not a replacement of GraphQL but similar to it

for more info: https://github.com/agamitechnologies/MinRoute

Why min-route ?

-Removes the complexity on the server caused by routes.
-Reduces lines of  code. 
-Secures the controller files.
Excited? Better, let’s get started.

Server Setup:

Step 1: create node project

Create a desired folder on your required location.

(here we’ll create folder “server” inside crud folder on desktop )

Open terminal inside the folder and type the below command and hit enter 

>> npm init

Add the required information in the terminal and begin the project.

Step 2: Install the required packages

In this tutorial, we will use only few libraries like 

-express
-body-parser
-http
-min-route
-request-ip
-express-useragent
-mongoose

We can install these all libraries by just using npm i command

>>>npm i express body-parser http min-route request-ip express-useragent mongoose

To match with the same version of libraries, here are my versions of installed packages.

Step 3: Setup server index file

Create a file with the name “index.js” in the folder with the following code.

Index.js

const express = require(‘express’);
const minRoute = require(‘min-route’);
const requestIp = require(‘request-ip’);
const useragent = require(‘express-useragent’);
const bodyParser = require(“body-parser”);
require(“./config/database”);
const app = express();
app.use(bodyParser.json({ limit: “50mb”, extended: true}))  
.use(express.static(“public”))   
.use( bodyParser.urlencoded({extended: false,  limit: “100mb”})   )  
 .use(requestIp.mw())
.use(useragent.express())
.use((request, response, next) => { 
response.header(“Access-Control-Allow-Origin”, “*”);       
response.header( “Access-Control-Allow-Methods”,          
  “GET,HEAD,OPTIONS,POST,PUT,DELETE”       ); 
response.header(“Access-Control-Allow-Headers”, 
  “Access-Control-Allow-Headers,
Origin, X-Requested-With, Content-Type,
Accept, Authorization, refreshToken”);     
   next();
});
app.listen(9000, () => { console.log(‘server running..’) })

Step 4: create a database model for the data we will be managing.
Create a models folder and inside create a file ‘user.js’ (as will be dealing with user’s data for now )

models/user.js

const mongoose = require(“mongoose”);

const userSchema = new Schema({   
email: {
type: String, default: null
},   
phone: {
type: String, default: null
},   
name: {
type: String, default: null
}
});
module.exports = mongoose.model(‘User’, userSchema);

Step 5: Create the DAO (Data Access Object) folder. 

This will be used for accessing the database directly. Inside the folder create a user.js file

dao/user.js

const user = require(“../models/user”);
const Mongoose = require(“mongoose”);
const objectId = Mongoose.Types.ObjectId;

module.exports.getUsers = async () => {   
return await user.find({})
}

module.exports.addUser = async (obj) => {   
return await user(obj).save();
}
module.exports.deleteUser = async (id) => {   
return await user.deleteOne({ _id: objectId(id) })
}
module.exports.updateUser = async (body) => {  
return await user.updateOne(
{ _id: objectId(body._id) },
{ email: body.email,
phone: body.phone,
name: body.name   }
)
}

The function names created inside clearly say what they’re used for.

Step 6: create the controller folder. 

Controller is used to handle the api calls from the client side. As other folders, it will be also having the user.js file

/controller/user.js

const userDao = require(‘../dao/user’)
const getUser = async (req, res) => {   
let user = await userDao.getUsers()   
return res.status(200).send({ data: user });
}
const postUser = async (req, res) => {   
let userObj = {   email: req.body.email,  
name: req.body.name, 
phone: req.body.phone   }   
await userDao.addUser(userObj);
   return res.status(200).send({ message: ‘data posted’ });
}
const deleteUser = async (req, res) => {   
await userDao.deleteUser(req.body.id); 
   return res.status(200).send({ message: ‘deleted successfully’ });
}
const updateUser = async (req, res) => { 
await userDao.updateUser(req.body);   
return res.status(200).send({ message: ‘updated successfully’ });
}
module.exports = { getUser, postUser, deleteUser, updateUser }

Step 6: create the config folder. 

Config folder will have the configuration files. Here we’ll require only one configuration i.e. database connectivity (mongoDB).

Create a database.js file inside the folder

/config/database.js

const mongoose = require(“mongoose”);

mongoose.connect(‘mongodb://localhost:27017/crud’,
{   
useFindAndModify: false, 
useNewUrlParser: true,   
useUnifiedTopology: true,   
useCreateIndex: true,   
poolSize: 20
}).then(() => {   
console.log(‘DB connection established to Database);
}).catch(error => {   
console.error(‘Could not establish mongoose connection’, error);
})

Adding min-route to project

Using min-route is super easy, few lines of code and we’re done with routes setup on the server side.

-index.js: 

Add the highlighted line in the index.js just above the app.listen() command.

minRoute.api(app, [`${__dirname}/controller/user.js`])
app.listen(9000, () => { console.log(‘server running..’) });

-controller/user.js:

Add the line at the very top of your controller file.


/** @controller = controller001 **/

Client setup:

We’ll be creating a Vue app for the front-end. We can create in any other framework or library. It won’t be an issue. 

As this tutorial is focussed on use of min-route so, we won’t be going in detail on the client side. Only the important and required part will be discussed here.

Step 1: create a client folder

Step 2: create the client in  any react, vue, angular framework/library or even simple html page.

Step 3: add the api calls 

We won’t be using any package to send api calls. Simple Javascript fetch() will work for this. You can use any external library.

We have to create the functions for each api request which can be called according to the requirements in the project.

GET API  

const getAllUsers = async () => {      
await fetch(‘http://localhost:9000/controller001.getUser’,
{   method: ‘GET’,         
   headers: {         
      ‘Content-Type’: ‘application/json’,      
     }}).then(data => {    
   return data.json();        
  }).catch(e => {               
console.log(e);           
});
  }
  •  POST API

const addUser = async (e) => {

       await fetch(‘http://localhost:9000/controller001.postUser’,{           
method: ‘POST’,
           headers: {
               ‘Content-Type’: ‘application/json’,
           },
           body: JSON.stringify({
name : ‘user1’, email: ‘user1@gmail.com’, phone: ‘1234567890’
           })
       }).then(data => {
           if (data.ok) console.log(‘Data added Successfully’)
       }).catch(e => {
           console.log(e);
       });
   }

  • UPDATE  API

const updateUser = async (e) => {

await fetch(‘http://localhost:9000/controller001.updateUser’, {           

method: ‘PUT’,
           headers: {
               ‘Content-Type’: ‘application/json’,
           },
           body: JSON.stringify({
           _id: ‘62e12b8edd84116355a653ba’, name: ‘user1’, 
email: ‘user2@getnada.com’, phone: ‘9898989898’ })
       }).then((data) => {
           if (data.ok) console.log(‘Data updated Successfully’)
       }).catch(e => {
           console.log(e)
 }); }

  • DELETE API 
const deleteUser = async (e) => {       
await fetch(‘http://localhost:9000/controller001.deleteUser’, {       
   method: ‘DELETE’,
headers: {
‘Content-Type’: ‘application/json’, 
}, 
 body: JSON.stringify({ id:‘62e12b8edd84116355a653ba’ })
 }).then(data => {
console.log(Data Deleted successfully’); 
}).catch(e => { 
console.log(e) });   
}

Here Values and data can be made dynamic according to the requirement, I have used static data just to demonstrate you.

The highlighted code in our api call is our main hero here. 

Syntax : controllerAlias.controllerName

controllerAlias is the controller file and controllerName is the controller  name to be called for that call. In our case, ‘controllerOO1’ here is the controller file to be looked for. And then is the controller (function) which should be called in that file. As here for get, post, put, delete we have  getUser, postUser,  updateUser, deleteUser respectively which all are in our controller file. 

Hurray, We’re done! Our Crud application is created.   

Thank you, Happy Learning.

You can check out the complete CRUD example from github. Go to Project

And for more advanced usage like middleware and params, min-route can be easily used.  To know more click here