📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (176K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
Before getting started, let's quickly see what is Express and Mongoose.
Express
Read more about express js at https://expressjs.com.
MongoDB and Mongoose
Setup MongoDB
You can also install the Zip version of MongoDB on Windows, check out this article at Install MongoDB on Windows 10.
Tools and technologies used
- node.js (npm)
- express
- body-parser
- mongoose
- visual studio code IDE
Development steps
- Creating an application
- Install dependencies
- Setting up the webserver
- Configuring and Connecting to the database
- Defining the Todo model in Mongoose
- Defining Routes using Express
- Developing the Restful APIs
- Testing our APIs
- Conclusion
- Source code on GitHub repository
1. Creating an application
- Open a terminal and create a new folder for the application.
$ mkdir todo-app
- Initialize the application with a package.json file
$ cd todo-app
$ npm init
{
"name": "todo-app",
"version": "1.0.0",
"description": "Todo App",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"Express",
"RestAPI",
"MongoDB",
"Mongoose",
"Todos"
],
"author": "javaguides.net",
"license": "MIT"
}
2. Install dependencies
$ npm install express body-parser mongoose --save
{
"name": "todo-app",
"version": "1.0.0",
"description": "Todo App",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"Express",
"RestAPI",
"MongoDB",
"Mongoose",
"Todos"
],
"author": "javaguides.net",
"license": "MIT",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"mongoose": "^5.9.2"
}
}
3. Setting up the webserver
const express = require('express');
const bodyParser = require('body-parser');
// create express app
const app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))
// parse application/json
app.use(bodyParser.json())
// define a simple route
app.get('/', (req, res) => {
res.json({"message": "Welcome to Todo app"});
});
// listen for requests
app.listen(4000, () => {
console.log("Server is listening on port 4000");
});
$ npm install
$ node main.js
Server is listening on port 4000
4. Configuring and Connecting to the database
$ mkdir config
$ cd config
module.exports = {
url: 'mongodb://localhost:27017/todos'
}
// Configuring the database
const dbConfig = require('./config/database.config.js');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
// Connecting to the database
mongoose.connect(dbConfig.url, {
useNewUrlParser: true
}).then(() => {
console.log("Successfully connected to the database");
}).catch(err => {
console.log('Could not connect to the database. Exiting now...', err);
process.exit();
});
const express = require('express');
const bodyParser = require('body-parser');
// create express app
const app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))
// parse application/json
app.use(bodyParser.json())
// Configuring the database
const dbConfig = require('./config/database.config.js');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
// Connecting to the database
mongoose.connect(dbConfig.url, {
useNewUrlParser: true
}).then(() => {
console.log("Successfully connected to the database");
}).catch(err => {
console.log('Could not connect to the database. Exiting now...', err);
process.exit();
});
// define a simple route
app.get('/', (req, res) => {
res.json({"message": "Welcome to Todo app"});
});
require('./app/routes/todo.routes.js')(app);
// listen for requests
app.listen(4000, () => {
console.log("Server is listening on port 4000");
});
$ node main.js
Server is listening on port 4000
Successfully connected to the database
5. Defining the Todo model in Mongoose
$ mkdir -p app/models
$ cd app/models
const mongoose = require('mongoose');
const TodoSchema= mongoose.Schema({
name: String,
description: String
}, {
timestamps: true
});
module.exports = mongoose.model('Todo', TodoSchema);
6. Defining Routes using Express
$ mkdir app/routes
$ cd app/routes
module.exports = (app) => {
const todos = require('../controllers/todo.controller.js');
// Create a new todo
app.post('/todos', todos.create);
// Retrieve all todos
app.get('/todos', todos.findAll);
// Retrieve a single todo by id
app.get('/todos/:id', todos.findOne);
// Update a Todo with id
app.put('/todos/:id', todos.update);
// Delete a Todo by id
app.delete('/todos/:id', todos.delete);
}
require('./app/routes/todo.routes.js')(app);
Note that We have added a required statement for the todo.controller.js file. We’ll define the controller file in the next section. The controller will contain methods for handling all the CRUD operations.
7. Developing the Restful APIs
Create a Todo
// Create and Save a new Todo
exports.create = (req, res) => {
// Validate request
if(!req.body.description) {
return res.status(400).send({
message: "Todo description can not be empty"
});
}
// Create a Todo
const todo = new Todo({
name: req.body.name || "Untitled Todo",
description: req.body.description
});
// Save Todo in the database
todo.save()
.then(data => {
res.send(data);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating the Todo."
});
});
};
Retrieve all Todos
// Retrieve and return all todos from the database.
exports.findAll = (req, res) => {
Todo.find()
.then(todos => {
res.send(todos);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while retrieving todos."
});
});
};
Retrieve a single Todo by Id
// Find a single todo with a id
exports.findOne = (req, res) => {
Todo.findById(req.params.id)
.then(todo => {
if(!todo) {
return res.status(404).send({
message: "Todo not found with id " + req.params.id
});
}
res.send(todo);
}).catch(err => {
if(err.kind === 'ObjectId') {
return res.status(404).send({
message: "Todo not found with id " + req.params.id
});
}
return res.status(500).send({
message: "Error retrieving todo with id " + req.params.id
});
});
};
Update a Todo
// Update a todo identified by the id in the request
exports.update = (req, res) => {
// Validate Request
if(!req.body.description) {
return res.status(400).send({
message: "Todo description can not be empty"
});
}
// Find todo and update it with the request body
Todo.findByIdAndUpdate(req.params.id, {
title: req.body.name || "Untitled Todo",
description: req.body.description
}, {new: true})
.then(todo => {
if(!todo) {
return res.status(404).send({
message: "Todo not found with id " + req.params.id
});
}
res.send(todo);
}).catch(err => {
if(err.kind === 'ObjectId') {
return res.status(404).send({
message: "Todo not found with id " + req.params.id
});
}
return res.status(500).send({
message: "Error updating todo with id " + req.params.id
});
});
};
Delete a Todo
// Delete a todo with the specified id in the request
exports.delete = (req, res) => {
Todo.findByIdAndRemove(req.params.id)
.then(todo => {
if(!todo) {
return res.status(404).send({
message: "Todo not found with id " + req.params.id
});
}
res.send({message: "Todo deleted successfully!"});
}).catch(err => {
if(err.kind === 'ObjectId' || err.name === 'NotFound') {
return res.status(404).send({
message: "Todo not found with id " + req.params.todo
});
}
return res.status(500).send({
message: "Could not delete todo with id " + req.params.id
});
});
};
const Todo = require('../models/todo.model.js'); // Create and Save a new Todo exports.create = (req, res) => { // Validate request if(!req.body.description) { return res.status(400).send({ message: "Todo description can not be empty" }); } // Create a Todo const todo = new Todo({ name: req.body.name || "Untitled Todo", description: req.body.description }); // Save Todo in the database todo.save() .then(data => { res.send(data); }).catch(err => { res.status(500).send({ message: err.message || "Some error occurred while creating the Todo." }); }); }; // Retrieve and return all todos from the database. exports.findAll = (req, res) => { Todo.find() .then(todos => { res.send(todos); }).catch(err => { res.status(500).send({ message: err.message || "Some error occurred while retrieving todos." }); }); }; // Find a single todo with a id exports.findOne = (req, res) => { Todo.findById(req.params.id) .then(todo => { if(!todo) { return res.status(404).send({ message: "Todo not found with id " + req.params.id }); } res.send(todo); }).catch(err => { if(err.kind === 'ObjectId') { return res.status(404).send({ message: "Todo not found with id " + req.params.id }); } return res.status(500).send({ message: "Error retrieving todo with id " + req.params.id }); }); }; // Update a todo identified by the id in the request exports.update = (req, res) => { // Validate Request if(!req.body.description) { return res.status(400).send({ message: "Todo description can not be empty" }); } // Find todo and update it with the request body Todo.findByIdAndUpdate(req.params.id, { title: req.body.name || "Untitled Todo", description: req.body.description }, {new: true}) .then(todo => { if(!todo) { return res.status(404).send({ message: "Todo not found with id " + req.params.id }); } res.send(todo); }).catch(err => { if(err.kind === 'ObjectId') { return res.status(404).send({ message: "Todo not found with id " + req.params.id }); } return res.status(500).send({ message: "Error updating todo with id " + req.params.id }); }); }; // Delete a todo with the specified id in the request exports.delete = (req, res) => { Todo.findByIdAndRemove(req.params.id) .then(todo => { if(!todo) { return res.status(404).send({ message: "Todo not found with id " + req.params.id }); } res.send({message: "Todo deleted successfully!"}); }).catch(err => { if(err.kind === 'ObjectId' || err.name === 'NotFound') { return res.status(404).send({ message: "Todo not found with id " + req.params.todo }); } return res.status(500).send({ message: "Could not delete todo with id " + req.params.id }); }); };
8. Testing our APIs
Create a new Todo using POST /todos API
Retrieving all Todos using GET /todos API
Retrieving a single Todo using GET /todos/:id API
Updating a Todo using PUT /todos/:id API
Deleting a Todo using DELETE /todos/:id API
9. Conclusion
If you found this tutorial useful then follow me at https://www.javaguides.net/p/about-me.html.
thank you for your tutorial
ReplyDelete