Express Yourself with MongoDB: Your First API, No Tears Attached 😭➡️😄
Want to build your own REST API and connect it to MongoDB? You’re in the right place! In this tutorial, we’ll walk through creating a full CRUD API using Node.js, Express, and MongoDB (with Mongoose) — step by step, from scratch. If you are absolutel...

Want to build your own REST API and connect it to MongoDB? You’re in the right place!
In this tutorial, we’ll walk through creating a full CRUD API using Node.js, Express, and MongoDB (with Mongoose) — step by step, from scratch.
If you are absolutely new to Rest API and it’s hand on then you can check out my blog like Rest API basics and Rest API hands on( with no db ) .
This is not a mongo DB crash course but a hands on guide to make REST api with B-son database ie. mongoDB
What We’ll Build
We’ll create a simple Product API where you can:
Create a product
Read all or single products
Update a product
Delete a product
Prerequisites
Make sure you have these installed:
Node.js + npm
MongoDB (local or MongoDB Atlas)
VS Code or any code editor
Project Setup
1. Initialize a Node project
mkdir api-mongodb
cd api-mongodb
npm init -y
2. Install dependencies
npm install express mongoose dotenv
npm install nodemon --save-dev
Update package.json
:
"scripts": {
"dev": "nodemon index.js"
}
or Just Grab my starter kit and start the tutorial
A reusable boilerplate? 👉 api-boilerplates GitHub
Setup the Server
3. Create index.js
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv"
import productRouter from "./routes/productRoutes.js";
import catagoryRouter from "./routes/catagoryRoutes.js";
dotenv.config()
const app = express()
app.use(express.json())
const mongoURI = process.env.mongo_string_url
mongoose.connect(mongoURI)
mongoose.connection.on("connected", () => {
console.log(`Mongo Db is connected`)
app.listen(5000, () => {
console.log(`server is running on 5000`)
})
})
mongoose.connection.on("error", (error) => {
console.log("error is ", error)
})
app.use("/api/products", productRouter);
app.use("/api/catagories", catagoryRouter)
Add .env
Create a .env
file:
MONGO_URI=your-mongodb-connection-uri
PORT=5000
Define the Product Model
4. Create models/Product.js
import mongoose from "mongoose";
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
description: {
type: String,
},
price: {
type: Number,
required: true
},
quantity: {
type: Number,
default: 0
},
active: {
type: Boolean,
default: true
},
catagory: {
type: String,
enum: ["food", "electronics", "vegetable"]
},
}, {
timestamps: true,
}
)
export default mongoose.model("ProductModel", productSchema);
Build the Routes
5. Create routes/productRoutes.js
import express from "express";
import { createProducts, deleteProduct, getProducts, getProductsById, updateProduct } from "../controllers/productsControler.js";
const router = express.Router()
router.post("/", createProducts)
router.get("/", getProducts)
router.get("/:id", getProductsById)
router.put("/:id", updateProduct)
router.delete("/:id",deleteProduct);
export default router;
Write the Logic
6. Create controllers/productController.js
import mongoose from "mongoose";
import productsModels from "../models/productsModels.js";
export const createProducts = async (req, res) => {
try {
if (!req.body.name) {
return res.status(422).json({
"error": "name feild is not given"
})
}
if (!req.body.description) {
return res.status(422).json({
"error": "description feild is not given"
})
}
if (!req.body.price) {
return res.status(422).json({
"error": "price feild is not given"
})
}
if (!req.body.quantity) {
return res.status(422).json({
"error": "quantity feild is not given"
})
}
if (!req.body.active) {
return res.status(422).json({
"error": "active feild is not given"
})
}
if (!req.body.catagory) {
return res.status(422).json({
"error": "catagory feild is not given"
})
}
const product = await productsModels
.create(req.body)
res.status(201).json(product)
}
catch (error) {
return res.status(501).json({
"error": error.message
})
}
}
export const getProducts = async (req, res) => {
try {
const product = await productsModels.find()
return res.status(201).json(product)
} catch (error) {
return res.status(422).json({
"error": "Invalid product ID"
})
}
}
export const getProductsById = async (req, res) => {
try {
const product = await productsModels.findById(req.params.id).select("_id name price")
return res.status(201).json(product)
} catch (error) {
return res.status(422).json({
"error": "Invalid product ID"
})
}
}
export const updateProduct = async (req, res) => {
if (!mongoose.isValidObjectId(req.params.id)) {
return res.status(422).json({
"error": "Invalid Mongo ID"
})
}
if (!await product.exists({ _id: req.params.id })) {
return res.status(422).json({
"error": "Invalid product ID"
})
}
try {
const product = await productsModels.findByIdAndUpdate(req.params.id, req.body, { new: true })
res.status(201).json({
product
})
} catch (error) {
return res.status(422).json({
"error": error.message
})
}
}
export const deleteProduct = async (req, res) => {
if (!mongoose.isValidObjectId(req.params.id)) {
return res.status(422).json({
"error": "Invalid Mongo ID"
})
}
if (!await product.exists({ _id: req.params.id })) {
return res.status(422).json({
"error": "Invalid product ID"
})
}
try {
const product = await productsModels.findByIdAndDelete(req.params.id);
if (!product) {
return res.status(404).json({ error: "Product not found" });
}
return res.status(200).json({
message: "Product deleted successfully"
});
} catch (error) {
return res.status(500).json({
error: error.message
});
}
}
Test Your API
Use Postman or Thunder Client to test your endpoints:
POST
/api/products
GET
/api/products
GET
/api/products/:id
PUT
/api/products/:id
DELETE
/api/products/:id
Done! What’s Next?
Now that you’ve built a working REST API with MongoDB, you can:
Add validation with Zod/Joi
Add user authentication with JWT
Deploy to Render, Vercel, or Railway
Starter Code
Full working code: 👉 api-mongodb GitHub
Need a reusable boilerplate? 👉 api-boilerplates GitHub
Final Words
You just built your first production-ready API! Whether you’re learning or planning to scale, this gives you a solid backend foundation.
If you found this useful, give it a ⭐ on GitHub and follow me for more content!