0% found this document useful (0 votes)
2 views12 pages

n6 Book Store API Development

The document provides a detailed guide on setting up a MongoDB-backed Express API, including creating a project structure, using nodemon for automatic server restarts, and handling routes and database connections. It emphasizes best practices for URL formatting, error handling, and code cleanliness, particularly in the context of updating book records in a MongoDB collection. Additionally, it explains the significance of using req.body in Express for handling incoming JSON data from client requests.

Uploaded by

vidir32659
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views12 pages

n6 Book Store API Development

The document provides a detailed guide on setting up a MongoDB-backed Express API, including creating a project structure, using nodemon for automatic server restarts, and handling routes and database connections. It emphasizes best practices for URL formatting, error handling, and code cleanliness, particularly in the context of updating book records in a MongoDB collection. Additionally, it explains the significance of using req.body in Express for handling incoming JSON data from client requests.

Uploaded by

vidir32659
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd

00:00 Intro & demo

MongoDB → new cluster →


Un: storeOwner0001
ps:B00ksAR3H3R3

>> [Link] →
"main": "[Link]", {"name": "book-store-api", "version": "1.0.0",
"main": "[Link]", "scripts": {"test": "echo \"Error: no test specified\" && exit 1",
"start": "node [Link]", "dev": "nodemon [Link]" },

>> no more manually restarting server for every update → solution → nodemon → [Link]

>> Install express , mongoose and dotenv →

>> create a db file inside the folder > database/[Link] , models folder ,routes(for different routes), controllers
folder(for logic) and “.env” file → 3:45 :40
>> Helpers folder , middleware folder(middleware logic) →

>> .env
PORT = 3000
3000; , the semicolon ”;” was causing the error , b’se the adress was localhost:3000 but
became localhost:3000;
😂 Yep — that tiny semicolon killed the whole API.
Postman treats:
[Link]

and
[Link]
as completely different URLs — the second one is invalid, so the connection gets refused.

🔍 Why it happened
Postman interprets the URL literally. The ; makes it no longer a valid port or hostname.
So instead of sending:
GET → localhost:3000

it tries:
GET → localhost:3000; (invalid host)

and you get:


ECONNREFUSED [Link]:3000;

🧠 Best Practice Tip:


Always format URLs cleanly — no trailing /, no accidental characters:

✔ Good:
[Link]
[Link]

❌ Bad:
[Link]
[Link]
[Link]

Since your server is working → try a POST test route:


POST → [Link]

Body (JSON):
{ "title": "Clean Code",
"author": "Robert Martin" }

>> [Link] →
const mongoose = require("mongoose");

const connectToDB = async () => {


try { await
[Link]("mongodb+srv://storeOwner0001:B00ksAR3H3R3@[Link]/" );
[Link]("mongoDB is connected successfully!");
} catch (error) { [Link]("MongoDB connection failed", error);
[Link](1); } };

[Link] = connectToDB;

>> [Link] →
>> Running the server
🔹 In models/[Link]
[Link] = [Link]("Book", bookSchema);

Here you're exporting a model class — something you will use to:

• create documents (new Book({...}))

• query ([Link]())

• update ([Link]())

• delete ([Link]())

So this export represents a MongoDB Collection interface.

Example usage:
const Book = require("./models/Book");

const books = await [Link](); // Using the exported model

So in this file you're exporting a mongoose model instance.

🔹 In [Link]
[Link] = connectToDB;

This exports a function, not a model.


Its job is simply to connect the app to MongoDB.

Example [Link]:
const mongoose = require("mongoose");

async function connectToDB() {


await [Link]([Link].MONGO_URI);
[Link]("DB Connected"); }

[Link] = connectToDB;

Usage in your main app:


const connectToDB = require("./db");
connectToDB();

So here you're exporting a utility function, not a model.


>> naming convention →
Good question — this is mostly about convention, not strict rules.
Mongoose will work whether you name it [Link], [Link], or [Link] — but developers follow patterns to
keep things clean.

✅ Common & Recommended Convention


📁 models/[Link]
👉 File name starts with capital letter if it contains a class-like export (model).

Because:
const Book = [Link]("Book", bookSchema);

Book behaves like a class (constructor for documents), so naming the file similarly makes sense.
📌 Why PascalCase for Models?
Because when you import it, you typically write:
const Book = require("./models/Book");

This makes sense because you later use it as a constructor:


const newBook = new Book({ title: "One Piece" });

It behaves like a class, so class naming convention fits.

❓ What happens in MongoDB collection?


Even though your model name is Book, Mongoose will automatically create the collection:
books

Plural + lowercase — that's Mongoose convention.

Example:
[Link]("Person") → "people"
[Link]("Mouse") → "mice"
[Link]("Book") → "books"

🔥 Short Answer
👉 Yes — using [Link] with capital B is the common and recommended convention.
It’s not required technically, but it follows class naming style and industry patterns.
>> get byID
>> Why this update funciton works →
const updateBook = async (req, res) => {
try {
const updatedBookFormData = [Link];
const getCurrentBookID = [Link];

// ✅ Validate request body exists


if (!updatedBookFormData || [Link](updatedBookFormData).length === 0) {
return [Link](400).json({ success: false, message: "Request body is empty. Please provide data to
update.", }); }

[Link]("📝 Update data received:", updatedBookFormData); // ✅ Debug log


[Link]("🆔 Book ID:", getCurrentBookID); // ✅ Debug log

const updatedBook = await [Link](


getCurrentBookID , updatedBookFormData,
{ new: true, // Return updated document
runValidators: true, // Run schema validators } );

[Link]("📚 Updated book:", updatedBook); // ✅ Debug log

[Link](200).json({ success: true,


message: "Book updated successfully",
data: updatedBook, });
} catch (e) { [Link](e);
[Link](500).json({ success: false, message: "Something went wrong! Please try again", }); } };

It worked because you fixed three problems that the previous version had:

✅ 1. You returned a response in all cases


In your older code, if the book exists, you didn’t send any response — so Postman kept loading forever.

Now you always respond:

• If body empty → 400

• After update → 200

• If error → 500

→ No hanging request.

✅ 2. You added validation before updating


You added this:
if (!updatedBookFormData || [Link](updatedBookFormData).length === 0) {
return [Link](400).json({
success: false,
message: "Request body is empty." }); }
This prevents sending empty updates, which protects your database and avoids bad requests.

✅ 3. You added runValidators: true


This is IMPORTANT.

Without this:
runValidators: true

Mongoose would update even with invalid data (wrong type, missing required fields, etc.)

With it enabled, your update respects your schema validation.

>> clean version →


Production version below in page 12.
in clean code you just removed the console and comments and rest there is no change →
ChatGPT said:
Exactly — you caught it. 😄

The logic didn’t change — only cleanliness changed.

The "clean version" is just:

• ❌ No logs

• ❌ No commented-out code

• ❌ No redundant debug messages

• ❌ No unused variables

Everything else is identical.

🧹 Why this matters (real-world reason)


In debugging mode, we keep stuff like:
[Link]("🆔 Book ID:", [Link]);
[Link]("📚 Updated book:", updatedBook);

But in production:

• Logs can leak data

• Logs clutter the output

• Comments become noise

• Someone reading code later gets confused


🧠 Rule of Thumb for Comments:
👉 If the code explains itself, NO comment needed.
👉 Only comment when something is:

• Complex

• Not obvious

• A workaround

• A business rule/requirement

Examples:
// ❌ BAD (obvious)
const price = 10; // set price to 10

// ❌ BAD (comments shouldn’t repeat code)


const updatedBook = await [Link](id, data, { new: true });
// update book with id using new data

// ✅ GOOD (explains WHY, not WHAT)


const token = generateJWT([Link]);
// JWT expires in 15 min for security compliance

>> Production code →


const updateBook = async (req, res) => {
try { const updateData = [Link];
const bookId = [Link];

// Validate if there's data to update


if (!updateData || [Link](updateData).length === 0) {
return [Link](400).json({ success: false, message: "No data provided for update", }); }

const updatedBook = await [Link](bookId, updateData, { new: true, runValidators: true, //


Ensures schema rules apply on update });

[Link](200).json({ success: true, message: "Book updated successfully", data: updatedBook, });
} catch (e) { [Link](e);
[Link](500).json({ success: false, message: "Something went wrong! Please try again", }); } };

[Link] is the input from the body of postman


ChatGPT said:
Yep — exactly.

[Link] in Express is whatever data the client (Postman, browser, frontend, mobile app, etc.) sends in the
request body when using methods like:
• POST
• PUT
• PATCH

🔍 How it works
You enabled this line in your server:
[Link]([Link]());

That middleware tells Express:

"If someone sends JSON in the request body — parse it and make it available as [Link]."

Example in Postman:
You send a POST request to:
POST [Link]

With this JSON inside Body → Raw → JSON:


{ "title": "Harry Potter", "author": "J.K. Rowling", "price": 499 }
Then in Express:
[Link]([Link]);

Output will be:


{ title: "Harry Potter", author: "J.K. Rowling", price: 499 }
🚨 Important Notes
• [Link] will NOT work without [Link]() OR a body parser.

• GET requests normally do not have a body.

• For GET, data usually comes from [Link] or [Link].

Summary:
✔ Yes, [Link] is the JSON (or form data) sent from Postman or frontend.
✔ Express parses it using [Link]().
✔ Used mainly in POST / PUT / PATCH operations.

You might also like