DEV Community

Samiul Bashar
Samiul Bashar

Posted on • Edited on

CRUD Example using Node.js, Express.js, MongoDB

In this post we will learn about basic CRUD operation by using Node.js and MongoDB.
CRUD is the fundamental concept for any web application.

In this CRUD application, we use the Task model to create task for a to-do application.
Here the Task model will contain

  • id

  • title

  • description

  • created time

  • updated time

Now, We Will create the model for Task...

const { Schema, model } = require('mongoose')

const taskSchema = new Schema({
    title: {
        type: String
    },
    description: {
        type: String
    }
}, {
    timestamps: true
})

const Task = model('Task', taskSchema)
module.exports = Task
Enter fullscreen mode Exit fullscreen mode

Now we will create the Server and connect server to the database.

require('dotenv').config()

const express = require('express')
const mongoose = require('mongoose')
const http = require('http')

const setMiddlewares = require('./middleware/middlewares')
const setRoutes = require('./router/routes')



const app = express()
const server = http.createServer(app)

setMiddlewares(app)
setRoutes(app)


const PORT = process.env.PORT || 1000
const DB_USER = process.env.DB_USER
const DB_PASSWORD = process.env.DB_PASSWORD
const DB_NAME = process.env.DB_NAME



mongoose.connect(`mongodb+srv://DB_USER :DB_PASSWORD 1@mycluster.oazue.mongodb.net/DB_NAME?retryWrites=true&w=majority`, { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => {
        console.log('Database connect success')
        server.listen(PORT, () => {
            console.log('Server Is Ready')
        })
    }).catch(e => {
        return console.log(e)
    })
Enter fullscreen mode Exit fullscreen mode

Now, we will create the controller for create task, read task, update task and delete task.

Create Task Controller:

exports.createTaskController = async(req, res, next) => {
    try {
        let { title, description } = req.body
        let newTask = new Task({
            title,
            description
        })

        await newTask.save(newTask)
            .then(data => {
                return res.send(data)
            }).catch(err => {
                res.status(500).send({
                    msg: 'task create fail'
                })
            })

        console.log(newTask)
    } catch (e) {
        console.log(e)
        next()
    }
}
Enter fullscreen mode Exit fullscreen mode

Read All Task Controller:

exports.getTaskController = async(req, res, next) => {
    try {
        await Task.find()
            .then(tasks => {
                return res.send(tasks)
            }).catch(err => {
                res.status(500).send({
                    msg: 'no tast found'
                })
            })

    } catch (e) {
        console.log(e)
        next()
    }
}
Enter fullscreen mode Exit fullscreen mode

Read Single Task Controller:

exports.getSingleTask = async(req, res, next) => {
    try {
        let taskId = req.params.id
        await Task.findById(taskId)
            .then(task => {
                if (task) {
                    return res.send(task)
                } else {
                    return res.send({ msg: 'no task found' })
                }

            }).catch(err => {
                res.status(500).send({
                    msg: 'no task found'
                })
            })

    } catch (e) {
        console.log(e)
        next()
    }
}
Enter fullscreen mode Exit fullscreen mode

Update Task Controller:

exports.updateTastController = async(req, res, next) => {
    try {
        let taskId = req.params.id
        let { title, description } = req.body
        let task = await Task.findById(taskId)
        console.log(task)
        if (!task) {
            return res.json({ msg: 'no task found' })
        }

        await Task.findByIdAndUpdate(taskId, {
            $set: {
                title,
                description
            }
        }, { new: true }).then(data => {
            return res.send(data)
        }).catch(err => {
            res.status(500).send({
                msg: 'task update fail'
            })
        })

    } catch (e) {
        console.log(e)
        next()
    }
}
Enter fullscreen mode Exit fullscreen mode

Delete Task Controller:

exports.deleteTaskController = async(req, res, next) => {
    try {
        let taskId = req.params.id
        await Task.findByIdAndDelete(taskId)
            .then(data => {
                return res.send(data)
            }).catch(err => {
                res.status(500).send({
                    msg: 'task delete fail'
                })
            })
    } catch (e) {
        console.log(e)
    }
}
Enter fullscreen mode Exit fullscreen mode

Now we create the route for all operation
route.js:

const crudRoute = require('../router/cruduRoute')

const routes = [{
        path: '/tasks',
        handler: crudRoute
    },
    {
        path: '/',
        handler: (req, res, next) => {
            return res.json({ msg: 'Welcome to my application' })
        }
    }
]

module.exports = (app) => {
    routes.forEach(r => {
        if (r.path == '/') {
            app.get(r.path, r.handler);
        } else {
            app.use(r.path, r.handler)
        }
    })
}
Enter fullscreen mode Exit fullscreen mode

crudRoute.js:

const router = require('express').Router()
const { getTaskController, getSingleTask, createTaskController, updateTastController, deleteTaskController } = require('../controller/crudController')


router.get('/', getTaskController)
router.get('/:id', getSingleTask)
router.post('/create', createTaskController)
router.put('/update/:id', updateTastController)
router.delete('/delete/:id', deleteTaskController)

module.exports = router
Enter fullscreen mode Exit fullscreen mode

Now we can run our project, and get all the output:
Create Task:
api:http://localhost:1000/tasks/create
JSON Data:
Image description
Image description
Get All Tasks
api:http://localhost:1000/tasks/

[
  {
    "_id": "62eaa8fff44996bbc06820ba",
    "title": "this is title",
    "description": "this is the description",
    "createdAt": "2022-08-03T16:57:35.029Z",
    "updatedAt": "2022-08-03T16:57:35.029Z",
    "__v": 0
  },
  {
    "_id": "62eaa90af44996bbc06820bc",
    "title": "this is title",
    "description": "this is the description",
    "createdAt": "2022-08-03T16:57:46.439Z",
    "updatedAt": "2022-08-03T16:57:46.439Z",
    "__v": 0
  },
  {
    "_id": "62eaa90bf44996bbc06820c0",
    "title": "this is title",
    "description": "this is the description",
    "createdAt": "2022-08-03T16:57:47.883Z",
    "updatedAt": "2022-08-03T16:57:47.883Z",
    "__v": 0
  },
  {
    "_id": "62eaa90cf44996bbc06820c2",
    "title": "this is title",
    "description": "this is the description",
    "createdAt": "2022-08-03T16:57:48.794Z",
    "updatedAt": "2022-08-03T16:57:48.794Z",
    "__v": 0
  },
  {
    "_id": "62eab011dc6db60de9a247c0",
    "title": "this is title",
    "description": "this is the description",
    "createdAt": "2022-08-03T17:27:45.876Z",
    "updatedAt": "2022-08-03T17:27:45.876Z",
    "__v": 0
  }
]

Enter fullscreen mode Exit fullscreen mode

Get Single Task
api:http://localhost:1000/tasks/62eaa8fff44996bbc06820ba

Image description
Update Task
api:http://localhost:1000/tasks/update/62eaa8fff44996bbc06820ba
Image description
Image description
Delete Tasks
api:http://localhost:1000/tasks/delete/62eaa8fff44996bbc06820ba

Full Code:
app.js

require('dotenv').config()

const express = require('express')
const mongoose = require('mongoose')
const http = require('http')

const setMiddlewares = require('./middleware/middlewares')
const setRoutes = require('./router/routes')



const app = express()
const server = http.createServer(app)

setMiddlewares(app)
setRoutes(app)


const PORT = process.env.PORT || 1000
const DB_USER = process.env.DB_USER
const DB_PASSWORD = process.env.DB_PASSWORD
const DB_NAME = process.env.DB_NAME



mongoose.connect(`mongodb+srv://DB_USER :DB_PASSWORD @mycluster.oazue.mongodb.net/DB_NAME ?retryWrites=true&w=majority`, { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => {
        console.log('Database connect success')
        server.listen(PORT, () => {
            console.log('Server Is Ready')
        })
    }).catch(e => {
        return console.log(e)
    })
Enter fullscreen mode Exit fullscreen mode

middleware.js

const express = require('express')
const morgan = require('morgan')


const middlewares = [
    morgan('dev'),
    express.urlencoded({ extended: true }),
    express.json()
]

module.exports = (app) => {
    middlewares.forEach(m => {
        app.use(m)
    })
}
Enter fullscreen mode Exit fullscreen mode

Task.js

const { Schema, model } = require('mongoose')

const taskSchema = new Schema({
    title: {
        type: String
    },
    description: {
        type: String
    }
}, {
    timestamps: true
})

const Task = model('Task', taskSchema)
module.exports = Task
Enter fullscreen mode Exit fullscreen mode

crudController.js

const Task = require('../model/Task')


// get all tasks
exports.getTaskController = async(req, res, next) => {
    try {
        await Task.find()
            .then(tasks => {
                return res.send(tasks)
            }).catch(err => {
                res.status(500).send({
                    msg: 'no tast found'
                })
            })

    } catch (e) {
        console.log(e)
        next()
    }
}

// get single task

exports.getSingleTask = async(req, res, next) => {
    try {
        let taskId = req.params.id
        await Task.findById(taskId)
            .then(task => {
                if (task) {
                    return res.send(task)
                } else {
                    return res.send({ msg: 'no task found' })
                }

            }).catch(err => {
                res.status(500).send({
                    msg: 'no task found'
                })
            })

    } catch (e) {
        console.log(e)
        next()
    }
}


// create task
exports.createTaskController = async(req, res, next) => {
    try {
        let { title, description } = req.body
        let newTask = new Task({
            title,
            description
        })

        await newTask.save(newTask)
            .then(data => {
                return res.send(data)
            }).catch(err => {
                res.status(500).send({
                    msg: 'task create fail'
                })
            })

        console.log(newTask)
    } catch (e) {
        console.log(e)
        next()
    }
}

//update task 

exports.updateTastController = async(req, res, next) => {
    try {
        let taskId = req.params.id
        let { title, description } = req.body
        let task = await Task.findById(taskId)
        console.log(task)
        if (!task) {
            return res.json({ msg: 'no task found' })
        }

        await Task.findByIdAndUpdate(taskId, {
            $set: {
                title,
                description
            }
        }, { new: true }).then(data => {
            return res.send(data)
        }).catch(err => {
            res.status(500).send({
                msg: 'task update fail'
            })
        })

    } catch (e) {
        console.log(e)
        next()
    }
}

// delete task 

exports.deleteTaskController = async(req, res, next) => {
    try {
        let taskId = req.params.id
        await Task.findByIdAndDelete(taskId)
            .then(data => {
                return res.send(data)
            }).catch(err => {
                res.status(500).send({
                    msg: 'task delete fail'
                })
            })
    } catch (e) {
        console.log(e)
    }
}
Enter fullscreen mode Exit fullscreen mode

routes.js

const crudRoute = require('../router/cruduRoute')

const routes = [{
        path: '/tasks',
        handler: crudRoute
    },
    {
        path: '/',
        handler: (req, res, next) => {
            return res.json({ msg: 'Welcome to my application' })
        }
    }
]

module.exports = (app) => {
    routes.forEach(r => {
        if (r.path == '/') {
            app.get(r.path, r.handler);
        } else {
            app.use(r.path, r.handler)
        }
    })
}
Enter fullscreen mode Exit fullscreen mode

crudRoute.js

const router = require('express').Router()
const { getTaskController, getSingleTask, createTaskController, updateTastController, deleteTaskController } = require('../controller/crudController')


router.get('/', getTaskController)
router.get('/:id', getSingleTask)
router.post('/create', createTaskController)
router.put('/update/:id', updateTastController)
router.delete('/delete/:id', deleteTaskController)

module.exports = router
Enter fullscreen mode Exit fullscreen mode

package.json

{
    "name": "backend",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "nodemon app.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "dotenv": "^16.0.1",
        "express": "^4.18.1",
        "express-validator": "^6.14.2",
        "moment": "^2.29.4",
        "mongoose": "^6.5.0",
        "morgan": "^1.10.0",
        "multer": "^1.4.5-lts.1",
        "nodemon": "^2.0.19"
    }
}
Enter fullscreen mode Exit fullscreen mode

Files
Image description

Top comments (4)

Collapse
 
canmingir profile image
Can Mingir • Edited

Hey Samiul, great article, just a quick tip, if you add the format next to your code blocks like in picture below, markdown will highlight for you

Image description

Collapse
 
samiulbashar19 profile image
Samiul Bashar

Thanks for your suggestion

Collapse
 
canmingir profile image
Can Mingir

np and there is a typo in the title 😀

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Hello. Try wj-config instead of dotenv. Lots more flexible, smarter for sure and also covers environment variables.