Creating A Simple Crud App With Nodejs

Creating A Simple Crud App With Nodejs

INTRODUCTION

A CRUD application is one in which there is a Create-Read-Update-Delete of Data from a database. This is common with most web application these days, as there is need to create and affect data in everyday's life.

Requirement

  • Nodejs=> You can download it from there official page here

  • A text editor to write and run your code. In my case i'm using visual studio code. You can get it here

  • An App to test your Api- In my case i would be using Postman.You can get it here. I also use a visual studio extension named thunder client for mini project Api testing.

GETTING STARTED

Step 1 - Creating the app Folder

Open your command prompt,Create a folder and give it a name of your choice in my case ,i would use hashnode_crud,navigate to the folder and open it with vsCode

mkdir hashnode_crud && cd hashnode_crud && code .

Step 2 - Configuring our app and Installing neccessary packages

Run the below code to quick start the creation of your package.json file, the '-y' flag is optional,if you want to customize your app run the command without it

 npm init  - y

The screenshot below describe the content in the created package.json file

Screenshot from 2022-05-22 22-11-36.png

npm i express morgan dotenv mongodb mongoose  --save

Creating the environment variable

Firstly ,create a file called index.js and then another file called .env. The index file is the root file for our app in which our major code would be while the .env file is the one in which houses our environment variable

inside your index.js write the following code as shown below

Step 3 Setting up your project root folder(index.js)

  • Import the neccessary packages and instatntiate the express app and start our server
// Configure the environment variable
require('dotenv').config()

//Module Exports
const express = require('express');
const logger= require('morgan');
const bodyparser = require('body-parser');
// Initiating our express app
const app = express()

// Configuration of server port
const PORT = process.env.PORT || 4000

// Basic Routing
app.get('/',(req,res)=>{
    res.json({message:'Api is working'}) 
})

app.listen(PORT,()=>{
    console.log("=========================================================") //Just for design, Does nothng special

    console.log("\x1b[36m%s\x1b[0m",`Server is now running on http://localhost:${PORT}`) //The first part before the console message is just for design.

    console.log("========================================================") //Just for design, Does nothng special

})

Open your browser and go to localhost:4000, you should see something similar to the screenshot below :

Screenshot from 2022-05-24 11-18-07.png

  • Add the neccessary middleware to the app
.
.
.
.
const app = express() 
// Middlewares
// logging our route calls to the console
app.use(logger('dev'));


//Middleware to handle your post request
app.use(bodyparser.json()) //This allows us to be able to read json data from our form body
.
.
.
.
  • Let connect our DB to our App First create a folder and call it models, inside the models folder create a file and call it product.js, The essence of this file is to create a schema data representation of the data that would be in our database(if you don't understand these terminologies, no trouble, i would be dropping an article on database soonest, wait for it...)

Inside the product.js file copy this code and paste it there

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var Product = new Schema({
    price: { type: String,required: true},
    name: { type: String, required: true },
    quantity: {type: Number, required: true},
})


module.exports = mongoose.model('products', Product);

In our > index.js, Let do some tweaking, Just after the app.use(bodyparser.json()), add your Database configuration there as shown below

.
.
.
.
app.use(bodyparser.json()) //This allows us to be able to read json data from our form

//Connecting our app to our DB
mongoose.connect(process.env.MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
})
const dbConnection = mongoose.connection;
dbConnection.on('connected',()=>{
    console.log("***************************************************") //Just for design, Does nothng special
    console.log("\x1b[36m%s\x1b[0m","Database is up and running...") 
    console.log("***************************************************") //Just for design, Does nothng special
})
dbConnection.on('disconnected',()=>{
    console.log("***************************************************") //Just for design, Does nothng special
    console.log("\x1b[31m%s\x1b[0m","Database is disconneted and Reconnect to continue transcation...")
    console.log("***************************************************") //Just for design, Does nothng special
})

dbConnection.on('err',console.error.bind('Databse refussed to connect, Try again'))


// Configuration of server port
const PORT = process.env.PORT || 4000
.
.
.
.

And at the import session at the top of your index.js file, inlude these two imports as shown below,

.
.
.
.

const DB = require('./model/product');
const mongoose = require(`mongoose`);
.
.
.
.

Then create a > .env file and input your connection url to your MongoDb database.(Let me know in the comment session if you don't know how to go about this). It should be like below,The user should be change to the user connected to your databse and password should be the user's password and dbName should be any name you need for your database.

MONGO_URI =mongodb+srv://user:password@dbName.d43tn.mongodb.net/?retryWrites=true&w=majority

Step 4- Routing

These is where we would apply our routing for creating,reading, deleting and updating our products in/from the database.The route should be written below the first route (app.get('/',(req,res)=>...),under the basic route in your index.js file

We make use of insertMany because we want to save an array of object.You could have use the insertOne or save read more here

  1. Creating our product in the database
// Creating Product - Verb (POST)
app.post('/create/product',async (req,res)=>{
    let data  = req.body
    await DB.insertMany(data,function (err,result) { 
        if (err) return res.json({status:503,response:err.message})
        // saved!
      });
    return  res.json({status:200,message:"Product Added successfully"}) 

})
  1. Reading our data from the databse

Getting All Product

// Get all product
app.get('/read/allProducts',(req,res)=>{
    const products = DB.find({},(err,product)=>{
    if(err) return  res.json({status:500,message:err.message})
    if(!products) return  res.json({status:405,reponse:"Product is not in database"})
    if(!err) return  res.json({status:200,response:"Products Fetched successfully",products:product})
    })
})

Get a particulat Product by it ID

app.get(`/read/product/:id`,(req,res)=>{

    let id = req.params.id // putting the params in a variable

    // querrying the database
    DB.findOne({_id:id},(err,product)=>{
        //Just some verification
        if(err) return  res.json({status:500,response:err.message})
        if(!id) return res.json({status:403,response:"Provide a valid parameter"})
        if(!product) return res.json({staus:403, response:"No products with this parameter in our database"})
        return(res.json({status:200,response:"Product fetched successfully", product:product}))
    })
})
  1. Updating a particular product by it ID
//Updating A Product 
app.post(`/product/update/:id`,(req,res)=>{
    let id = req.params.id // putting the params in a variable
    let data = req.body
    // querrying the database
   DB.findOneAndUpdate({_id:id},data,(err,product)=>{
        if(err) return  res.json({status:500,response:err.message})
        if(!product) return  res.json({status:500,response:"Product not found in the database"}) // Will Fire this if the id provided is wrong
        return(res.json({status:200,response:"Product updated successfully"}))
    })

})
  1. Delete a Particular Product from the database
//Deleting Product
app.post(`/product/delete/:id`,(req,res)=>{
    let id = req.params.id // putting the params in a variable
    // querrying the database
    DB.findByIdAndDelete({_id:id},(err,product)=>{
        if(err) return  res.json({status:500,response:err.message})
        if(!product) return  res.json({status:500,response:"Product not found in the database"}) // Will Fire this if the id provided is wrong
        return(res.json({status:200,response:"Product deleted successfully"}))
    })

})

Testing Our End Point

  1. Create User

Screenshot from 2022-05-25 12-02-12.png

2)a) Get All Products Note pay attention to the Verbs POST and GET and use them appropriately

Screenshot from 2022-05-25 12-05-10.png

b) Get a particular Product by it ID(From the get all product endpoint copy a produuct ID and use it in this endpoint

Screenshot from 2022-05-25 12-10-54.png

3) Update a particular Product by it Id, You can hit the get all products endpoint to see the changes.

Screenshot from 2022-05-25 12-14-26.png

4)Delete A particular product by it Id,You can hit the get all products endpoint to see the changes.

Screenshot from 2022-05-25 12-17-03.png

PUTTING ALL TOGETHER

index.js


// Configure the environment variable
require('dotenv').config()

//Module Exports
const express = require('express');
const logger= require('morgan');
const bodyparser = require('body-parser');
const DB = require('./model/product');
const mongoose = require(`mongoose`);

// Initiating our express app
const app = express()



// Middlewares
// logging our route calls to the console
app.use(logger('dev'));

//Middleware to handle your post request
app.use(bodyparser.json()) //This allows us to be able to read json data from our form

//Connecting our app to our DB
mongoose.connect(process.env.MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
})
const dbConnection = mongoose.connection;
dbConnection.on('connected',()=>{
    console.log("***************************************************") //Just for design, Does nothng special
    console.log("\x1b[36m%s\x1b[0m","Database is up and running...") 
    console.log("***************************************************") //Just for design, Does nothng special
})
dbConnection.on('disconnected',()=>{
    console.log("***************************************************") //Just for design, Does nothng special
    console.log("\x1b[31m%s\x1b[0m","Database is disconneted and Reconnect to continue transcation...")
    console.log("***************************************************") //Just for design, Does nothng special
})

dbConnection.on('err',console.error.bind('Databse refussed to connect, Try again'))


// Configuration of server port
const PORT = process.env.PORT || 4000


// Basic Routing
app.get('/',(req,res)=>{
    res.json({message:'Api is working'}) 
})



// Creating Product - Verb (POST)
app.post('/create/product',async (req,res)=>{
    let data  = req.body
    await DB.insertMany(data,function (err,result) {
        if (err) return res.json({status:503,response:err.message})
        // saved!
      });
    return  res.json({status:200,message:"Product Added successfully"}) 

})



//Reading Product 


// Get all product
app.get('/read/allProducts',(req,res)=>{
    const products = DB.find({},(err,product)=>{
    if(err) return  res.json({status:500,message:err.message})
    if(!products) return  res.json({status:405,reponse:"Product is not in database"})
    if(!err) return  res.json({status:200,response:"Products Fetched successfully",products:product})
    })
})

// Get product by id in the database

app.get(`/read/product/:id`,(req,res)=>{

    let id = req.params.id // putting the params in a variable

    // querrying the database
    DB.findOne({_id:id},(err,product)=>{
        //Just some verification
        if(err) return  res.json({status:500,response:err.message})
        if(!id) return res.json({status:403,response:"Provide a valid parameter"})
        if(!product) return res.json({staus:403, response:"No products with this parameter in our database"})
        return(res.json({status:200,response:"Product fetched successfully", product:product}))
    })
})

//Updating Product 
app.post(`/product/update/:id`,(req,res)=>{
    let id = req.params.id // putting the params in a variable
    let data = req.body
    // querrying the database
   DB.findOneAndUpdate({_id:id},data,(err,product)=>{
        if(err) return  res.json({status:500,response:err.message})
        if(!product) return  res.json({status:500,response:"Product not found in the database"}) // Will Fire this if the id provided is wrong
        return(res.json({status:200,response:"Product updated successfully"}))
    })

})


//Deleting Product
app.post(`/product/delete/:id`,(req,res)=>{
    let id = req.params.id // putting the params in a variable
    // querrying the database
    DB.findByIdAndDelete({_id:id},(err,product)=>{
        if(err) return  res.json({status:500,response:err.message})
        if(!product) return  res.json({status:500,response:"Product not found in the database"}) // Will Fire this if the id provided is wrong
        return(res.json({status:200,response:"Product deleted successfully"}))
    })

})

app.listen(PORT,()=>{
    console.log("=========================================================") //Just for design, Does nothng special

    console.log("\x1b[36m%s\x1b[0m",`Server is now running on http://localhost:${PORT}`)

    console.log("========================================================") //Just for design, Does nothng special

})

Conclusion

In Practice,Your files should be segmeneted into modules and not written in a just one file(This is done because it is a tutorial), you might have the config files which houses your databse configurations, you might have the controllers, where you can have your middlewares for your routes and the likes

You can drop your question here or send me a mail on .

Thank you for reading