MongoDB CRUD Operations with Express, Mongoose and Postman.

MongoDB CRUD Operations with Express, Mongoose and Postman.

·

3 min read

Introduction

In this blog post, I'll share my experience building a simple bookstore application using the MERN stack (MongoDB, Express, React, Node.js). I'll focus on setting up CRUD (Create, Read, Update, Delete) operations with Express Router and testing them with Postman. This project helped me understand how to structure a backend with Express and connect it to a MongoDB database.

Setting Up the Backend

Creating the Express Server

To start, I set up an Express server and only Listen to Client side requests when connection with the MongoDB atlas is Established Succesfully, Here is the code snippet for initializing the server:

import express from "express";
import { PORT, dbUrl } from "./config.js";
import { router as bookRouter } from "./routes/booksRouter.js";
import mongoose from "mongoose";
import Book from "./models/Book.js";
import cors from "cors";
const app = express();
app.use(express.json());
app.use(cors());
app.use("/books", bookRouter);
//listen to client Requests only after the Database connection is Success.
mongoose
  .connect(dbUrl)
  .then((result) => {
    app.listen(
      PORT,
      console.log("connected to Atlas & Listening on PORT", PORT)
    );
  })
  .catch((err) => console.log("Connection to Atlas Error", err));

Creating Schema and Model

In Mongoose, a schema defines the structure of the documents within a collection, specifying the types of data that each field can contain. A model is a wrapper for the schema that provides an interface to interact with the database, below is the code how i created Schema and Model using Mongoose.

import mongoose from "mongoose";

const bookSchema = mongoose.Schema(
  {
    title: {
      type: String,
      required: true,
    },
    author: {
      type: String,
      required: true,
    },
    publishedYear: {
      type: String,
      required: true,
    },
  },
  { timestamps: true }
);
const Book = mongoose.model("Book", bookSchema);
export default Book;

Setting Up API Endpoints with Express Router

Modularizing with Express Routers for Endpoint /books to keep the code clean and organized.

//index.js 
app.use("/books", bookRouter);
//bookRouter.js
import express from "express";
import Book from "../models/Book.js";
export const router = express.Router();
// it is /books route [view all Books]
router.get("/", async (req, res) => {
  try {
    const books = await Book.find();
    res.status(200).json({ count: books.length, body: books });
  } catch (error) {}
  res.status(404).send({ message: "Cannot Get the Books" });
});
//insert a new Book [Write]
router.post("/add-book", async (req, res) => {
  const { title, author, publishedYear } = req.body;
  //validate inputs for null
  if (title && author && publishedYear) {
    //insert a new Book
    const newBook = {
      title: title,
      author: author,
      publishedYear: publishedYear,
    };
    const savedResponse = await Book.create(newBook);
    res
      .status(200)
      .send({ message: "New Book Added Succesfully", data: savedResponse });
  } else {
    res.status(400).send({ message: "Please fill all required fields" });
  }
});
// get only Particular Book [view only one ]
router.get("/:id", async (req, res) => {
  const { id } = req.params;
  try {
    const book = await Book.findById(id);
    res.status(200).send(book);
  } catch (error) {
    res.status(400).send({ message: "Book Specified Not found" });
  }
});

// update a book
router.put("/:id", async (req, res) => {
  const { title, author, publishedYear } = req.body;
  const { id } = req.params;
  //validate inputs for null
  if (title && author && publishedYear) {
    //insert a new Book
    const updatedBook = {
      title: title,
      author: author,
      publishedYear: publishedYear,
    };
    const savedResponse = await Book.findByIdAndUpdate(id, updatedBook);
    res
      .status(200)
      .send({
        message: "New Book Added Succesfully",
        data: await Book.findById(id),
      });
  } else {
    res.status(400).send({ message: "Cannot Update the book, Not Found" });
  }
});
router.delete("/:id", async (req, res) => {
  const { id } = req.params;
  try {
    const result = await Book.findByIdAndDelete(id);
    res.status(200).send({ message: "Deleted Book Succesfully" });
  } catch (error) {
    res.status(400).send({ message: "Not found to Delete" });
  }
});

Using Postman to test these endpoints,

GET request: to get all the books

POST request: to add a new book

PUT request: Updating Existing Book.

DELETE request: to delete a Book