Building a Simple CRUD app with Node, Express, and MongoDB | Getting started with NodeJS | Book store app
Introduction
I finally understood how to work with Node, Express, and MongoDB. I want to write a comprehensive tutorial so you won’t have to go through the same headache I went through. In this tutorial, we will be building a Book store app and this is the first part.
Prerequisite
I assume that you have a basic understanding of Node.js. for this tutorial, we are going to use Node, Express, and MongoDB Atlas.
Directory Structure
First, create a directory whatever name you like, I have created a backend directory on my desktop.
Start Building
Open with the terminal and make sure you have installed node.js, to check that you have downloaded and installed or not type node -v
on your terminal. This command will show you your node version. Run npm init
to initialize your node project.
Install Packages
You need to install four packages or dependencies see the following package.json file. You can install it manually too, and run npm install dotenv express nodemon mongoose
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"dev": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^16.3.1",
"express": "^4.18.2",
"mongoose": "^7.5.2",
"nodemon": "^3.0.1"
}
}
Files Structure
Inside the backend directory that you created earlier, create an `index.js
file. Why? As you can see above in the package.json we have declared our main server file should be index.js
. But you change it. After that, you need to create a .env
file within the same directory, set your PORT and MongoDB connection string and replace your_password with your user password that you have to create while creating the MongoDB cluster.
PORT=3000
DB='mongodb+srv://shivam456:your_password@book-store.0sdws23.mongodb.net/'
Create Book Schema
First, see my directory structure and the following image contains a main directory which is a backend
the subdirectory is models
.
import mongoose from "mongoose";
const bookSchema = mongoose.Schema(
{
title: {
type: String,
require: true,
},
author: {
type: String,
require: true,
},
publishYear: {
type: Number,
require: true,
},
},
{
timestamps: true,
}
)
export const Book = mongoose.model("Cat", bookSchema);
Create your first express server
The following code should be in your index.js
file. Here you can see we have imported the Book schema that is coming from ./models/bookModel.js
means you need to create another directory within the backend directory. See my directory structure
import express from 'express'
import { config } from 'dotenv';
import mongoose from 'mongoose';
import { Book } from './models/bookModel.js';
config();
const PORT = process.env.PORT;
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
return res.status(200).send('Welcome to the Bookstore APP.');
});
// Route for Create a new booK
app.post('/books', async (req, res) => {
try {
if (
!req.body.title ||
!req.body.author ||
!req.body.publishYear
) {
return res.status(400)
.send({message: 'Send all required fields: title, author, publishYear'});
}
const newBook = {
title: req.body.title,
author: req.body.author,
publishYear: req.body.publishYear,
};
const book = await Book.create(newBook);
return res.status(201).send({book});
} catch (error) {
console.log(error.message);
res.status(500).send({message: error.message});
}
});
// Route for Get all books
app.get('/books', async (req, res) => {
try {
const books = await Book.find({});
return res.status(200).json({
count: books.length,
data: books,
});
} catch (error) {
console.log(error.message);
res.status(500).send({message: error.message});
}
});
// Route for Get a book by id
app.get('/books/:id', async (req, res) => {
try {
const books = await Book.findById(req.params.id);
if (!books) {
return res.status(404).send({message: 'Book not found'});
}
return res.status(200).json({
data: books,
});
} catch (error) {
console.log(error.message);
res.status(500).send({message: error.message});
}
});
// Route for Update a book by id
app.put('/books/:id', async (req, res) => {
try {
if (
!req.body.title ||
!req.body.author ||
!req.body.publishYear
) {
return res.status(400)
.send({message: 'Send all required fields: title, author, publishYear'});
}
const book = await Book.findByIdAndUpdate(req.params.id, req.body);
if (!book) {
return res.status(404).send({message: 'Book not found'});
}
return res.status(200).send({message: 'Book updated successfully'});
} catch (error) {
console.log(error.message);
res.status(500).send({message: error.message});
}
});
// Route for Delete a book by id
app.delete('/books/:id', async (req, res) => {
try {
const book = await Book.findByIdAndDelete(req.params.id);
if (!book) {
return res.status(404).send({message: 'Book not found'});
}
return res.status(200).send({message: 'Book deleted successfully'});
} catch (error) {
console.log(error.message);
res.status(500).send({message: error.message});
}
});
// Database connection
mongoose.connect(process.env.DB)
.then(() => {
console.log('App has Connected with Database')
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
})
.catch((error) => {
console.log(error);
})
Run book store app
Type npm run dev
on your terminal and then you have the same output as the following image.
Imported thing noticed on the above image that I run npm run dev
command from backend
directory which means from the root.