student notes / est. for the classroom

HTML, CSS, JavaScript, Python, data science, computer networks — written the way you'd explain it to a classmate, not a compiler.

Top Job & Internship Portals

Handpicked portals for fresher jobs, tech roles, and listings in Hyderabad

GFG

GeeksforGeeks

Tech & Software Roles

Visit →
INT

Internshala

Fresher Jobs & Internships

Visit →
GOOG

Google Careers

Global Google Openings

Visit →
APN

Apna Jobs

Local Jobs in Hyderabad

Visit →
INS

Instahyre

Tech Roles in Hyderabad

Visit →
NAUK

Naukri.com

Fresher Jobs in Hyderabad

Visit →
📢 Updated daily

Internship & Job Alerts

01

Latest notes

November 27, 2025

Web Development with MERN (data science)

 

Unit 1: Introduction to Web Development & Frontend with React

Topics:

  • Overview of web development: Frontend vs Backend vs Full-stack

  • HTML, CSS, JavaScript fundamentals

  • Introduction to React.js

    • Components, JSX, props, state

    • Functional vs Class components

    • Event handling & forms

  • React Hooks: useState, useEffect, useRef

  • Routing with React Router

  • Basic project: Build a simple React-based website

Practical:

  • Create a multi-page React app (e.g., portfolio or task tracker)


Unit 2: Backend Development with Node.js & Express.js

Topics:

  • Introduction to Node.js and its architecture

  • Setting up Express.js server

  • Routing & middleware

  • RESTful API design

  • Handling JSON requests and responses

  • Error handling in Express

  • Environment variables and configuration (dotenv)

Practical:

  • Build a simple REST API (e.g., user management with CRUD operations)


Unit 3: Database Management with MongoDB

Topics:

  • Introduction to NoSQL and MongoDB

  • Installing and connecting MongoDB with Node.js

  • CRUD operations using MongoDB

  • Mongoose ODM: Schemas, Models, and Validation

  • Data relationships in MongoDB

  • Query optimization and aggregation basics

Practical:

  • Integrate MongoDB with Express API

  • Build a backend for a small app (e.g., blog or task manager)


Unit 4: Full-Stack Integration & Advanced MERN Concepts

Topics:

  • Connecting React frontend with Express/MongoDB backend

  • Axios or Fetch API for HTTP requests

  • JWT-based authentication and authorization

  • Deployment strategies (Heroku, Vercel, Netlify)

  • State management with Redux or Context API

  • Project structure & best practices

  • Optional: Real-time updates with Socket.io

Practical:

  • Build a full-stack MERN project (e.g., e-commerce app, chat app, or task manager)

  • Deploy the project online



Lab Program 1: React Environment Setup & JSX Basics

Aim:
Set up a React development environment and understand JSX.

Tasks:

  • Install Node.js and create React app

  • Understand JSX syntax

  • Create functional components

  • Render components to the DOM

Unit Covered: Unit 1
Tools: Node.js, React


Lab Program 2: React Components, Props & State

Aim:
Implement component-based architecture in React.

Tasks:

  • Create reusable components

  • Pass data using props

  • Manage state using useState

  • Conditional rendering

Unit Covered: Unit 1


Lab Program 3: React Hooks, Forms & Routing

Aim:
Build a multi-page React application.

Tasks:

  • Form handling in React

  • useEffect and useRef hooks

  • Client-side routing using React Router

  • Navigation between pages

Example: Portfolio or Task Tracker
Unit Covered: Unit 1


Lab Program 4: Node.js & Express Server Setup

Aim:
Create a backend server using Express.js.

Tasks:

  • Setup Express server

  • Create routes

  • Use middleware

  • Send JSON responses

Unit Covered: Unit 2
Tools: Node.js, Express.js


Lab Program 5: RESTful API with CRUD Operations

Aim:
Design and implement a REST API.

Tasks:

  • Create REST endpoints (GET, POST, PUT, DELETE)

  • Handle JSON requests

  • Error handling in Express

  • Use Postman for testing

Example: User management system
Unit Covered: Unit 2


Lab Program 6: MongoDB Integration with Node.js

Aim:
Connect MongoDB with Express backend.

Tasks:

  • Install MongoDB and Mongoose

  • Create schemas and models

  • Perform CRUD operations

  • Input validation

Unit Covered: Unit 3


Lab Program 7: MongoDB Relationships & Aggregation

Aim:
Implement data relationships and aggregation.

Tasks:

  • Reference and embedded documents

  • Populate related data

  • Basic aggregation queries

  • Optimize database queries

Example: Blog with users and posts
Unit Covered: Unit 3


Lab Program 8: React + Backend Integration

Aim:
Connect React frontend with backend API.

Tasks:

  • Fetch data using Axios / Fetch API

  • Display backend data in React

  • Handle loading and error states

  • Environment variable usage

Unit Covered: Unit 4


Lab Program 9: Authentication with JWT

Aim:
Implement secure authentication and authorization.

Tasks:

  • User registration and login

  • Password hashing

  • JWT token generation

  • Protected routes in React

  • Middleware for authorization

Unit Covered: Unit 4


Lab Program 10: Full-Stack MERN Project & Deployment

Aim:
Develop and deploy a complete MERN stack application.

Options:

  • E-commerce app

  • Chat application

  • Task management system

Tasks:

  • Frontend + backend integration

  • State management (Context API / Redux)

  • Optional real-time features using Socket.io

  • Deploy frontend and backend

  • Project documentation

Unit Covered: Unit 4
Outcome: Capstone Project 🌟


LAB 1

🔹 Lab Program 1: React Environment Setup & JSX Basics

🎯 Aim

Set up a React development environment and understand JSX fundamentals.


✅ 1. Install Node.js & Create React App

Step 1: Install Node.js

Download and install the latest LTS version of Node.js from:
👉 https://nodejs.org

Verify installation:

node -v npm -v

Step 2: Create a React App

The modern way to create a React app is using Vite (faster than Create React App).

npm create vite@latest my-react-app cd my-react-app npm install npm run dev

Open the shown local URL (usually http://localhost:5173).


✅ 2. Understanding JSX

React uses JSX (JavaScript XML) — a syntax extension that looks like HTML but is written inside JavaScript.

Example:

const element = <h1>Hello, React!</h1>;

JSX Rules:

  • Must return a single parent element

  • Use className instead of class

  • JavaScript expressions go inside { }

Example:

const name = "Siva"; const element = <h2>Welcome {name}</h2>;

✅ 3. Create Functional Components

In React, components are reusable UI blocks.

Example: Functional Component

Inside App.jsx:

function Welcome() { return <h2>Welcome to React Lab!</h2>; } export default function App() { return ( <div> <h1>Hello World</h1> <Welcome /> </div> ); }

✅ 4. Render Components to the DOM

React renders components using createRoot.

Inside main.jsx:

import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; ReactDOM.createRoot(document.getElementById("root")).render( <React.StrictMode> <App /> </React.StrictMode> );

📌 Expected Output

When you open the browser:

Hello World Welcome to React Lab!

🎯 Learning Outcomes

After completing this lab, you should be able to:

  • Install and configure React environment

  • Understand JSX syntax

  • Create functional components

  • Render components into the browser DOM


LAB 2

🔹 Lab Program 2: React Components, Props & State

🎯 Aim

Implement component-based architecture in React.


✅ Task 1: Create Reusable Components

📁 Project Structure

src/ ├── App.jsx ├── components/ │ ├── Header.jsx │ ├── UserCard.jsx │ └── Counter.jsx

🔹 Header Component (Header.jsx)

function Header() { return <h1>React Lab Program 2</h1>; } export default Header;

🔹 UserCard Component (UserCard.jsx)

function UserCard({ name, age }) { return ( <div style={{ border: "1px solid gray", padding: "10px", margin: "10px" }}> <h3>Name: {name}</h3> <p>Age: {age}</p> </div> ); } export default UserCard;

✅ Task 2: Pass Data Using Props

Props allow data to be passed from parent to child.

🔹 Use Components in App.jsx

import Header from "./components/Header"; import UserCard from "./components/UserCard"; function App() { return ( <div> <Header /> <UserCard name="Siva" age={22} /> <UserCard name="Priya" age={21} /> </div> ); } export default App;

📌 Here:

  • name and age are passed as props.

  • Components become reusable with different data.


✅ Task 3: Manage State Using useState

React state allows components to store and update data dynamically.

🔹 Counter Component (Counter.jsx)

import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <div> <h2>Count: {count}</h2> <button onClick={() => setCount(count + 1)}>Increment</button> <button onClick={() => setCount(count - 1)}>Decrement</button> </div> ); } export default Counter;

🔹 Add Counter in App.jsx

import Counter from "./components/Counter"; function App() { return ( <div> <Header /> <UserCard name="Siva" age={22} /> <Counter /> </div> ); }

✅ Task 4: Conditional Rendering

Render UI based on conditions.

🔹 Example: Show Message Based on Count

Modify Counter.jsx:

{count > 5 ? ( <p style={{ color: "green" }}>High Count!</p> ) : ( <p style={{ color: "red" }}>Low Count</p> )}

OR using &&:

{count === 0 && <p>Counter is at initial value</p>}

📌 Expected Output

  • Header displayed

  • Multiple reusable UserCards

  • Counter with increment/decrement

  • Message changes based on count value


🎯 Learning Outcomes

After completing this lab, you can:

  • Create reusable React components

  • Pass and receive props

  • Manage dynamic data using useState

  • Implement conditional rendering


LAB 3

🔹 Lab Program 3: React Hooks, Forms & Routing

🎯 Aim

Build a multi-page application using React with hooks, forms, and routing.


✅ Task 1: Form Handling in React

📁 Project Structure

src/ ├── App.jsx ├── pages/ │ ├── Home.jsx │ ├── About.jsx │ └── Contact.jsx

🔹 Contact Form Example (Contact.jsx)

import { useState, useRef, useEffect } from "react"; function Contact() { const [formData, setFormData] = useState({ name: "", email: "" }); const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); // Auto focus on page load }, []); const handleChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value }); }; const handleSubmit = (e) => { e.preventDefault(); alert(`Name: ${formData.name}, Email: ${formData.email}`); }; return ( <div> <h2>Contact Page</h2> <form onSubmit={handleSubmit}> <input ref={inputRef} type="text" name="name" placeholder="Enter Name" value={formData.name} onChange={handleChange} /> <br /><br /> <input type="email" name="email" placeholder="Enter Email" value={formData.email} onChange={handleChange} /> <br /><br /> <button type="submit">Submit</button> </form> </div> ); } export default Contact;

✅ Task 2: useEffect and useRef Hooks

🔹 useEffect

  • Used for side effects (API calls, DOM updates, timers)

  • Runs after component renders

Example:

useEffect(() => { console.log("Component Mounted"); }, []);

🔹 useRef

  • Access DOM elements

  • Store mutable values without re-rendering

Example:

const countRef = useRef(0); countRef.current++;

✅ Task 3: Client-Side Routing

Install React Router

npm install react-router-dom

🔹 Setup Routing (App.jsx)

import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; function App() { return ( <Router> <nav> <Link to="/">Home</Link> | <Link to="/about"> About</Link> | <Link to="/contact"> Contact</Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </Router> ); } export default App;

🔹 Simple Page Components

Home.jsx

function Home() { return <h2>Welcome to Home Page</h2>; } export default Home;

About.jsx

function About() { return <h2>About Us Page</h2>; } export default About;

✅ Task 4: Navigation Between Pages

  • <Link> prevents full page reload

  • URL changes without refreshing

  • Navigation is smooth and fast

Example:

<Link to="/contact">Go to Contact</Link>

📌 Expected Output

  • Multi-page navigation (Home, About, Contact)

  • Working contact form

  • Auto-focus using useRef

  • Console log using useEffect

  • No page reload while switching pages


🎯 Learning Outcomes

After completing this lab, you can:

  • Handle forms in React

  • Use useState, useEffect, useRef

  • Implement client-side routing

  • Navigate between multiple pages


LAB 4

🔹 Lab Program 4: Node.js & Express Server Setup

🎯 Aim

Create a backend server using Node.js and Express.js.


✅ Step 1: Project Setup

1️⃣ Initialize Project

mkdir lab4-server cd lab4-server npm init -y

2️⃣ Install Express

npm install express

✅ Step 2: Setup Express Server

Create a file: server.js

const express = require("express"); const app = express(); const PORT = 5000; // Middleware to parse JSON app.use(express.json()); // Basic Route app.get("/", (req, res) => { res.send("Server is running successfully!"); }); // Start server app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); });

▶ Run Server

node server.js

Open:
👉 http://localhost:5000


✅ Step 3: Create Routes

Routes define API endpoints.

Add below routes in server.js:

// GET route app.get("/api/users", (req, res) => { const users = [ { id: 1, name: "Siva" }, { id: 2, name: "Priya" } ]; res.json(users); }); // POST route app.post("/api/users", (req, res) => { const newUser = req.body; res.json({ message: "User added successfully", user: newUser }); });

✅ Step 4: Use Middleware

Middleware runs before request reaches the route.

🔹 Custom Middleware Example

const logger = (req, res, next) => { console.log(`${req.method} ${req.url}`); next(); }; app.use(logger);

Now every request logs method and URL.


✅ Step 5: Send JSON Responses

Use:

res.json(data);

Example:

app.get("/api/status", (req, res) => { res.json({ success: true, message: "API is working" }); });

📌 Expected Output

  • Server runs on port 5000

  • / → Displays message

  • /api/users → Returns JSON list

  • /api/status → Returns JSON response

  • Logs every request in console


🎯 Learning Outcomes

After completing this lab, you can:

  • Initialize a Node project

  • Setup Express server

  • Create GET & POST routes

  • Use middleware

  • Send JSON responses


LAB 5

🔹 Lab Program 5: RESTful API with CRUD Operations

🎯 Aim

Design and implement a REST API using Node.js and Express.js.


✅ Step 1: Project Setup

mkdir lab5-rest-api cd lab5-rest-api npm init -y npm install express

Create server.js


✅ Step 2: Setup Express Server

const express = require("express"); const app = express(); const PORT = 5000; app.use(express.json()); // Middleware to parse JSON app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); });

✅ Step 3: Create REST Endpoints (CRUD)

We’ll simulate a database using an array.

let users = [ { id: 1, name: "Siva", age: 22 }, { id: 2, name: "Priya", age: 21 } ];

🔹 1️⃣ GET – Retrieve All Users

app.get("/api/users", (req, res) => { res.json(users); });

🔹 2️⃣ GET – Retrieve Single User

app.get("/api/users/:id", (req, res) => { const user = users.find(u => u.id === parseInt(req.params.id)); if (!user) { return res.status(404).json({ message: "User not found" }); } res.json(user); });

🔹 3️⃣ POST – Create New User

app.post("/api/users", (req, res) => { const { name, age } = req.body; if (!name || !age) { return res.status(400).json({ message: "Name and age are required" }); } const newUser = { id: users.length + 1, name, age }; users.push(newUser); res.status(201).json(newUser); });

🔹 4️⃣ PUT – Update User

app.put("/api/users/:id", (req, res) => { const user = users.find(u => u.id === parseInt(req.params.id)); if (!user) { return res.status(404).json({ message: "User not found" }); } const { name, age } = req.body; user.name = name || user.name; user.age = age || user.age; res.json(user); });

🔹 5️⃣ DELETE – Remove User

app.delete("/api/users/:id", (req, res) => { const userIndex = users.findIndex(u => u.id === parseInt(req.params.id)); if (userIndex === -1) { return res.status(404).json({ message: "User not found" }); } users.splice(userIndex, 1); res.json({ message: "User deleted successfully" }); });

✅ Step 4: Error Handling in Express

🔹 Global Error Handler Middleware

app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ message: "Something went wrong!" }); });

Example usage:

app.get("/error", (req, res, next) => { const err = new Error("Test error"); next(err); });

✅ Step 5: Testing with Postman

Use Postman to test endpoints.

🔹 Example Requests:

Set Body → Raw → JSON in Postman.


📌 Expected Output

  • API supports full CRUD

  • Proper status codes (200, 201, 400, 404, 500)

  • JSON responses

  • Errors handled properly


🎯 Learning Outcomes

After completing this lab, you can:

  • Design RESTful endpoints

  • Handle JSON requests and responses

  • Implement CRUD operations

  • Implement error handling

  • Test APIs using Postman


LAB 6

🔹 Lab Program 6: MongoDB Integration with Node.js

🎯 Aim

Connect MongoDB with an Express.js backend using Mongoose.


✅ Step 1: Install MongoDB & Dependencies

1️⃣ Install MongoDB

Download and install MongoDB Community Server from:
👉 https://www.mongodb.com/try/download/community

Start MongoDB service.


2️⃣ Install Required Packages

Inside your project folder:

npm init -y npm install express mongoose

✅ Step 2: Connect MongoDB with Node.js

Create server.js:

const express = require("express"); const mongoose = require("mongoose"); const app = express(); const PORT = 5000; app.use(express.json()); // Connect to MongoDB mongoose.connect("mongodb://127.0.0.1:27017/lab6db") .then(() => console.log("MongoDB Connected")) .catch(err => console.log(err)); // Start server app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); });

✅ Step 3: Create Schema & Model

Create folder: models/User.js

const mongoose = require("mongoose"); const userSchema = new mongoose.Schema({ name: { type: String, required: [true, "Name is required"] }, email: { type: String, required: true, unique: true }, age: { type: Number, min: 18 } }, { timestamps: true }); module.exports = mongoose.model("User", userSchema);

✅ Step 4: Perform CRUD Operations

Update server.js:

const User = require("./models/User"); // CREATE app.post("/api/users", async (req, res) => { try { const user = new User(req.body); const savedUser = await user.save(); res.status(201).json(savedUser); } catch (error) { res.status(400).json({ message: error.message }); } }); // READ (All) app.get("/api/users", async (req, res) => { const users = await User.find(); res.json(users); }); // READ (Single) app.get("/api/users/:id", async (req, res) => { try { const user = await User.findById(req.params.id); if (!user) return res.status(404).json({ message: "User not found" }); res.json(user); } catch (error) { res.status(400).json({ message: "Invalid ID" }); } }); // UPDATE app.put("/api/users/:id", async (req, res) => { try { const updatedUser = await User.findByIdAndUpdate( req.params.id, req.body, { new: true, runValidators: true } ); if (!updatedUser) return res.status(404).json({ message: "User not found" }); res.json(updatedUser); } catch (error) { res.status(400).json({ message: error.message }); } }); // DELETE app.delete("/api/users/:id", async (req, res) => { try { const deletedUser = await User.findByIdAndDelete(req.params.id); if (!deletedUser) return res.status(404).json({ message: "User not found" }); res.json({ message: "User deleted successfully" }); } catch (error) { res.status(400).json({ message: "Invalid ID" }); } });

✅ Step 5: Input Validation

Validation is handled via Mongoose schema:

name: { type: String, required: true } age: { type: Number, min: 18 } email: { type: String, unique: true }

If invalid data is sent:

  • Required fields missing → 400 error

  • Age < 18 → Validation error

  • Duplicate email → Error


✅ Step 6: Test Using Postman

Use Postman:

🔹 Example POST Request

POST http://localhost:5000/api/users

Body (JSON):

{ "name": "Siva", "email": "siva@gmail.com", "age": 22 }

📌 Expected Output

  • MongoDB connected successfully

  • Data stored in lab6db

  • Full CRUD working

  • Schema validation enforced

  • Proper error responses


🎯 Learning Outcomes

After completing this lab, you can:

  • Connect MongoDB with Express

  • Create schemas & models

  • Perform database CRUD operations

  • Implement validation using Mongoose

  • Handle async/await operations


LAB 7

🎯 Aim

Implement data relationships and aggregation using MongoDB with Mongoose in a Node.js + Express.js backend.


✅ 1️⃣ Reference & Embedded Documents

MongoDB supports two types of relationships:

🔹 A) Embedded Documents (One-to-Few)

Example: A user with multiple addresses embedded.

📁 models/User.js

const mongoose = require("mongoose"); const addressSchema = new mongoose.Schema({ street: String, city: String }); const userSchema = new mongoose.Schema({ name: String, email: String, addresses: [addressSchema] // Embedded documents }); module.exports = mongoose.model("User", userSchema);

Example Data:

{ "name": "Siva", "email": "siva@gmail.com", "addresses": [ { "street": "MG Road", "city": "Chennai" }, { "street": "Brigade Road", "city": "Bangalore" } ] }

✔ Best for small, tightly related data
✔ Faster reads


🔹 B) Referenced Documents (One-to-Many)

Example: One user → Many posts


📁 models/Post.js

const mongoose = require("mongoose"); const postSchema = new mongoose.Schema({ title: String, content: String, user: { type: mongoose.Schema.Types.ObjectId, ref: "User" } }); module.exports = mongoose.model("Post", postSchema);

✔ Better for large datasets
✔ Avoids duplication


✅ 2️⃣ Populate Related Data

populate() replaces ObjectId with actual document data.

Example Route

const Post = require("./models/Post"); app.get("/api/posts", async (req, res) => { const posts = await Post.find().populate("user"); res.json(posts); });

Output:

{ "title": "My First Post", "user": { "_id": "123", "name": "Siva", "email": "siva@gmail.com" } }

✅ 3️⃣ Basic Aggregation Queries

Aggregation is used for data analysis.

🔹 Count Users by City

app.get("/api/users-by-city", async (req, res) => { const result = await User.aggregate([ { $unwind: "$addresses" }, { $group: { _id: "$addresses.city", totalUsers: { $sum: 1 } } } ]); res.json(result); });

🔹 Average Age of Users

app.get("/api/average-age", async (req, res) => { const result = await User.aggregate([ { $group: { _id: null, averageAge: { $avg: "$age" } } } ]); res.json(result); });

✅ 4️⃣ Optimize Database Queries

🔹 A) Use Indexes

Add index in schema:

email: { type: String, unique: true, index: true }

Or manually:

userSchema.index({ email: 1 });

✔ Improves search speed
✔ Required for large datasets


🔹 B) Select Only Required Fields

User.find().select("name email");

✔ Reduces data transfer
✔ Faster response


🔹 C) Pagination

app.get("/api/users", async (req, res) => { const page = parseInt(req.query.page) || 1; const limit = 5; const users = await User.find() .skip((page - 1) * limit) .limit(limit); res.json(users); });

✔ Prevents large data loading


📌 Expected Output

  • Embedded documents working

  • Referenced documents working

  • populate() fetching related data

  • Aggregation queries returning grouped results

  • Indexed & optimized queries


🎯 Learning Outcomes

After completing this lab, you can:

  • Design relationships in MongoDB

  • Use embedded & referenced documents

  • Fetch related data using populate()

  • Perform aggregation queries

  • Optimize MongoDB performance


LAB 8

🔹 Lab Program 8: React + Backend Integration

🎯 Aim

Connect a React frontend with a Express.js backend API.


✅ Prerequisites

Make sure:

  • Backend server is running (e.g., http://localhost:5000)

  • React app is running (e.g., http://localhost:5173)

  • CORS is enabled in backend:

npm install cors
const cors = require("cors"); app.use(cors());

✅ 1️⃣ Fetch Data using Axios / Fetch API

Install Axios (optional):

npm install axios

🔹 Example Backend API (Express)

app.get("/api/users", (req, res) => { res.json([ { id: 1, name: "Siva", age: 22 }, { id: 2, name: "Priya", age: 21 } ]); });

🔹 Fetch Data in React (Using Axios)

📁 Users.jsx

import { useState, useEffect } from "react"; import axios from "axios"; function Users() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); useEffect(() => { axios .get(`${import.meta.env.VITE_API_URL}/api/users`) .then((response) => { setUsers(response.data); setLoading(false); }) .catch((err) => { setError("Failed to fetch data"); setLoading(false); }); }, []); if (loading) return <p>Loading...</p>; if (error) return <p>{error}</p>; return ( <div> <h2>User List</h2> {users.map((user) => ( <div key={user.id}> <p>{user.name} - {user.age}</p> </div> ))} </div> ); } export default Users;

✅ 2️⃣ Display Backend Data in React

Import in App.jsx:

import Users from "./Users"; function App() { return ( <div> <h1>React + Backend Integration</h1> <Users /> </div> ); } export default App;

✅ 3️⃣ Handle Loading & Error States

We handled:

  • loading → Shows "Loading..."

  • error → Shows error message

  • Success → Displays user list

This improves user experience and robustness.


✅ 4️⃣ Environment Variables Usage

Create .env file in React root:

VITE_API_URL=http://localhost:5000

⚠ Restart development server after adding .env.

Access inside React:

import.meta.env.VITE_API_URL

📌 Expected Output

  • React fetches data from backend

  • Data displayed dynamically

  • Loading message shown initially

  • Error message displayed if request fails

  • API URL managed via environment variable


🎯 Learning Outcomes

After completing this lab, you can:

  • Connect React frontend with backend API

  • Use Axios / Fetch API for HTTP requests

  • Manage loading & error states

  • Use environment variables securely

  • Understand frontend-backend communication flow


LAB 9

🔹 Lab Program 9: Authentication with JWT

🎯 Aim

Implement secure authentication and authorization using Node.js, Express.js, MongoDB, and React.


✅ Step 1: Install Required Packages

Backend Dependencies

npm install bcryptjs jsonwebtoken dotenv cors
  • bcryptjs → Password hashing

  • jsonwebtoken → Token generation

  • dotenv → Environment variables


✅ Step 2: User Model with Password Hashing

📁 models/User.js

const mongoose = require("mongoose"); const bcrypt = require("bcryptjs"); const userSchema = new mongoose.Schema({ name: String, email: { type: String, unique: true }, password: { type: String, required: true } }); // Hash password before saving userSchema.pre("save", async function (next) { if (!this.isModified("password")) return next(); this.password = await bcrypt.hash(this.password, 10); next(); }); module.exports = mongoose.model("User", userSchema);

✅ Step 3: User Registration

📁 routes/auth.js

const express = require("express"); const jwt = require("jsonwebtoken"); const bcrypt = require("bcryptjs"); const User = require("../models/User"); const router = express.Router(); // Register router.post("/register", async (req, res) => { try { const user = new User(req.body); await user.save(); res.status(201).json({ message: "User registered successfully" }); } catch (error) { res.status(400).json({ message: error.message }); } });

✅ Step 4: User Login & JWT Token Generation

router.post("/login", async (req, res) => { try { const { email, password } = req.body; const user = await User.findOne({ email }); if (!user) return res.status(400).json({ message: "Invalid credentials" }); const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) return res.status(400).json({ message: "Invalid credentials" }); const token = jwt.sign( { id: user._id }, process.env.JWT_SECRET, { expiresIn: "1h" } ); res.json({ token }); } catch (error) { res.status(500).json({ message: "Server error" }); } }); module.exports = router;

✅ Step 5: Environment Variables

Create .env file:

JWT_SECRET=mysecretkey

In server.js:

require("dotenv").config();

✅ Step 6: Middleware for Authorization

📁 middleware/auth.js

const jwt = require("jsonwebtoken"); module.exports = function (req, res, next) { const token = req.header("Authorization"); if (!token) { return res.status(401).json({ message: "Access Denied" }); } try { const verified = jwt.verify(token, process.env.JWT_SECRET); req.user = verified; next(); } catch (err) { res.status(400).json({ message: "Invalid Token" }); } };

✅ Step 7: Protected Route Example

const authMiddleware = require("./middleware/auth"); app.get("/api/profile", authMiddleware, (req, res) => { res.json({ message: "Welcome to protected route", user: req.user }); });

Now only users with valid JWT can access this route.


✅ Step 8: Protected Routes in React

Store token after login:

localStorage.setItem("token", response.data.token);

🔹 Axios with Authorization Header

axios.get("http://localhost:5000/api/profile", { headers: { Authorization: localStorage.getItem("token") } });

🔹 React Protected Route Example

import { Navigate } from "react-router-dom"; function ProtectedRoute({ children }) { const token = localStorage.getItem("token"); return token ? children : <Navigate to="/login" />; } export default ProtectedRoute;

Usage:

<Route path="/dashboard" element={ <ProtectedRoute> <Dashboard /> </ProtectedRoute> } />

📌 Expected Output

  • Users can register

  • Passwords stored securely (hashed)

  • Login returns JWT token

  • Protected routes require valid token

  • Unauthorized users cannot access protected data


🎯 Learning Outcomes

After completing this lab, you can:

  • Implement authentication with JWT

  • Hash passwords securely

  • Create login & registration APIs

  • Protect backend routes with middleware

  • Protect frontend routes in React

  • Understand authentication vs authorization


LAB 10

🔹 Lab Program 10: Full-Stack MERN Project & Deployment

🎯 Aim

Develop and deploy a complete MERN stack application using:

  • MongoDB

  • Express.js

  • React

  • Node.js


✅ Project Options (Choose One)

1️⃣ E-commerce App

  • User authentication

  • Product listing

  • Cart & checkout

  • Admin product management

2️⃣ Chat Application

  • User login

  • Real-time messaging

  • Online users

  • Message history

3️⃣ Task Management System (Recommended for Lab)

  • User authentication

  • Create / update / delete tasks

  • Task status tracking

  • Dashboard view


🏗 Suggested Project: Task Management System


✅ 1️⃣ Project Architecture

mern-project/ │ ├── backend/ │ ├── models/ │ ├── routes/ │ ├── middleware/ │ └── server.js │ └── frontend/ ├── src/ ├── components/ └── App.jsx

✅ 2️⃣ Backend Features

📌 APIs Required

MethodEndpointDescription
POST/api/auth/registerRegister user
POST/api/auth/loginLogin user
GET/api/tasksGet user tasks
POST/api/tasksCreate task
PUT/api/tasks/:idUpdate task
DELETE/api/tasks/:idDelete task

📌 Task Schema Example

const mongoose = require("mongoose"); const taskSchema = new mongoose.Schema({ title: String, description: String, status: { type: String, default: "pending" }, user: { type: mongoose.Schema.Types.ObjectId, ref: "User" } }, { timestamps: true }); module.exports = mongoose.model("Task", taskSchema);

✅ 3️⃣ Frontend Integration

Install Axios

npm install axios

Fetch Tasks Example

useEffect(() => { axios.get(`${import.meta.env.VITE_API_URL}/api/tasks`, { headers: { Authorization: localStorage.getItem("token") } }) .then(res => setTasks(res.data)) .catch(err => console.log(err)); }, []);

✅ 4️⃣ State Management

🔹 Option A: Context API (Simple Projects)

Create AuthContext.js:

import { createContext, useState } from "react"; export const AuthContext = createContext(); export function AuthProvider({ children }) { const [user, setUser] = useState(null); return ( <AuthContext.Provider value={{ user, setUser }}> {children} </AuthContext.Provider> ); }

Wrap in main.jsx.


🔹 Option B: Redux (Large Projects)

Use Redux for complex state handling.


✅ 5️⃣ Optional: Real-Time Features

Install Socket.io

Backend:

npm install socket.io

Frontend:

npm install socket.io-client

Example use cases:

  • Real-time task updates

  • Live chat messages

  • Notifications


✅ 6️⃣ Deployment

🔹 Backend Deployment

Deploy on:

  • Render

  • Railway

Steps:

  1. Push code to GitHub

  2. Connect GitHub repo to Render/Railway

  3. Add environment variables (MongoDB URI, JWT secret)

  4. Deploy


🔹 Frontend Deployment

Deploy on:

  • Vercel

  • Netlify

Steps:

  1. Push frontend to GitHub

  2. Import project

  3. Add environment variable:

VITE_API_URL=https://your-backend-url.com
  1. Deploy


✅ 7️⃣ Project Documentation

Include:

📄 README.md

  • Project title

  • Tech stack

  • Installation steps

  • API endpoints

  • Environment variables

  • Deployment links

📄 Screenshots

  • Login page

  • Dashboard

  • CRUD operations

  • Deployment proof


📌 Evaluation Checklist

✔ Frontend + backend fully integrated
✔ JWT authentication working
✔ CRUD operations implemented
✔ Proper error handling
✔ Environment variables configured
✔ Deployed successfully
✔ Clean folder structure
✔ README documentation


🎯 Learning Outcomes

After completing this lab, you can:

  • Build a complete MERN stack application

  • Integrate frontend & backend securely

  • Manage global state

  • Implement authentication

  • Deploy full-stack applications

  • Document and present projects professionally






UNIT 1

🌐 Overview of Web Development

Web development is generally divided into Frontend, Backend, and Full-Stack development. Each plays a different role in building web applications.


1️⃣ Frontend Development (Client-Side)

Frontend is everything users see and interact with in their browser.

🔹 Responsibilities:

  • Designing layouts

  • Styling pages

  • Creating interactive elements

  • Handling user input

  • Communicating with backend APIs

🔹 Technologies:

  • HTML – Structure

  • CSS – Styling

  • JavaScript – Interactivity

  • Frameworks/Libraries:

    • React

    • Angular

    • Vue.js

🔹 Example:

When you click a button on a website and a form appears without reloading the page — that’s frontend logic working.


2️⃣ Backend Development (Server-Side)

Backend works behind the scenes. It handles logic, database operations, authentication, and server communication.

🔹 Responsibilities:

  • Managing databases

  • Handling user authentication

  • Processing business logic

  • Creating APIs

  • Ensuring security

🔹 Technologies:

  • Programming languages:

    • Node.js

    • Python

    • Java

    • PHP

  • Databases:

    • MySQL

    • MongoDB

    • PostgreSQL

🔹 Example:

When you log in to a website and your credentials are verified using a database — that’s backend processing.


3️⃣ Full-Stack Development

A Full-Stack Developer works on both frontend and backend.

They:

  • Build UI

  • Create APIs

  • Connect frontend to backend

  • Manage databases

  • Deploy applications

Popular Full-Stack Combinations:

  • MERN Stack (MongoDB + Express + React + Node)

  • MEAN Stack (MongoDB + Express + Angular + Node)

  • Django + React

  • Spring Boot + React

Since you’re already working with React and backend systems, full-stack development would be a natural fit for you.


💻 HTML, CSS, JavaScript Fundamentals

These are the three core building blocks of the web.


🧱 1. HTML (HyperText Markup Language)

HTML defines the structure of a webpage.

Example:

<!DOCTYPE html> <html> <head> <title>My Website</title> </head> <body> <h1>Hello World</h1> <p>This is a paragraph.</p> <button>Click Me</button> </body> </html>

Key Concepts:

  • Elements (<h1>, <p>, <div>)

  • Attributes (id, class)

  • Forms (<input>, <form>)

  • Semantic tags (<header>, <footer>, <section>)

Think of HTML as the skeleton of a website.


🎨 2. CSS (Cascading Style Sheets)

CSS controls the appearance of a webpage.

Example:

body { background-color: lightblue; } h1 { color: darkblue; } button { padding: 10px; border-radius: 5px; }

Key Concepts:

  • Selectors (.class, #id)

  • Box model (margin, padding, border)

  • Flexbox

  • Grid

  • Responsive design (media queries)

CSS is the design and styling layer.


⚡ 3. JavaScript (JS)

JavaScript makes webpages interactive and dynamic.

Example:

document.querySelector("button").addEventListener("click", function() { alert("Button Clicked!"); });

Key Concepts:

  • Variables (let, const)

  • Functions

  • DOM Manipulation

  • Events

  • Fetching data from APIs

  • Async/Await

JavaScript is the brain of the frontend.


🔄 How They Work Together

LayerTechnologyPurpose
StructureHTMLBuilds content
StylingCSSMakes it look good
LogicJavaScriptMakes it interactive
Data & SecurityBackendHandles data & logic

🚀 Simple Real-World Flow

Example: User logs into a website

  1. HTML → Displays login form

  2. CSS → Styles the form

  3. JavaScript → Captures user input

  4. Backend → Verifies credentials

  5. Database → Stores/retrieves user data

⚛ Introduction to React.js

🔹 What is React?

React is a JavaScript library used to build interactive user interfaces, especially for single-page applications (SPAs).

It was developed by Meta.


🔹 Why React?

  • Component-based architecture

  • Reusable UI blocks

  • Fast rendering using Virtual DOM

  • Large ecosystem

  • Strong community support


🔹 How React Works

Instead of manipulating the DOM directly:

  • React creates a Virtual DOM

  • Compares changes

  • Updates only what is necessary

This makes React fast and efficient.


🧱 Components, JSX, Props, State


🔹 1. Components

Components are reusable building blocks of a React app.

Two types:

  • Functional Components (modern & recommended)

  • Class Components (older approach)

Example (Functional Component):

function Welcome() { return <h1>Hello React</h1>; }

Use it like:

<Welcome />

🔹 2. JSX

JSX = JavaScript XML

It allows you to write HTML inside JavaScript.

Example:

const element = <h1>Hello World</h1>;

Behind the scenes, JSX gets converted to:

React.createElement()

Rules:

  • Must return a single parent element

  • Use className instead of class

  • JavaScript inside {}

Example:

const name = "Rahul"; <h1>Hello {name}</h1>

🔹 3. Props

Props (short for properties) allow passing data from parent to child component.

Example:

function Greeting(props) { return <h1>Hello {props.name}</h1>; }

Usage:

<Greeting name="Rahul" />

You can also destructure:

function Greeting({ name }) { return <h1>Hello {name}</h1>; }

Props are read-only.


🔹 4. State

State allows a component to store and manage dynamic data.

In modern React, we use useState.

Example:

import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <> <h1>{count}</h1> <button onClick={() => setCount(count + 1)}> Increase </button> </> ); }
  • count → current state

  • setCount → function to update state

When state updates → component re-renders.


🔄 Functional vs Class Components


🔹 Functional Components (Recommended)

function MyComponent() { return <h1>Hello</h1>; }

With Hooks:

import { useState } from "react"; function MyComponent() { const [data, setData] = useState(""); return <div>{data}</div>; }

Advantages:

  • Cleaner syntax

  • Less code

  • Hooks support lifecycle

  • Industry standard today


🔹 Class Components (Older)

import React, { Component } from "react"; class MyComponent extends Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return <h1>{this.state.count}</h1>; } }

Used lifecycle methods like:

  • componentDidMount()

  • componentDidUpdate()

  • componentWillUnmount()

Today, Hooks replace lifecycle methods.


🖱 Event Handling & Forms


🔹 Event Handling in React

React events are written in camelCase.

Example:

function Button() { const handleClick = () => { alert("Button Clicked!"); }; return <button onClick={handleClick}>Click Me</button>; }

Common Events:

  • onClick

  • onChange

  • onSubmit

  • onMouseEnter


🔹 Forms in React

React uses controlled components for forms.

Controlled = Form data is controlled by state.


Example: Input Field

import { useState } from "react"; function FormExample() { const [name, setName] = useState(""); return ( <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> ); }

Example: Form Submission

function FormExample() { const [email, setEmail] = useState(""); const handleSubmit = (e) => { e.preventDefault(); alert(email); }; return ( <form onSubmit={handleSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} /> <button type="submit">Submit</button> </form> ); }

🎯 Key Concepts You Must Master

✔ Components
✔ JSX
✔ Props
✔ State
✔ Event handling
✔ Controlled forms
✔ Functional components + Hooks


⚛ React Hooks

Hooks let you use state and lifecycle features in functional components in React.


🪝 1️⃣ useState

useState is used to manage component state.

🔹 Syntax

const [state, setState] = useState(initialValue);

🔹 Example: Counter

import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <div> <h2>{count}</h2> <button onClick={() => setCount(count + 1)}> Increase </button> </div> ); }

When setCount runs → component re-renders.


🪝 2️⃣ useEffect

useEffect handles side effects like:

  • API calls

  • Timers

  • Event listeners

  • Component lifecycle behavior


🔹 Syntax

useEffect(() => { // side effect code }, [dependencies]);

🔹 Run Only Once (Component Mount)

useEffect(() => { console.log("Component mounted"); }, []);

Empty dependency array → runs once.


🔹 Run When State Changes

useEffect(() => { console.log("Count changed:", count); }, [count]);

🔹 Cleanup Example

useEffect(() => { const timer = setInterval(() => { console.log("Running..."); }, 1000); return () => { clearInterval(timer); }; }, []);

Cleanup runs when component unmounts.


🪝 3️⃣ useRef

useRef is used to:

  • Access DOM elements

  • Store values without causing re-render


🔹 Access Input Field

import { useRef } from "react"; function InputFocus() { const inputRef = useRef(); const focusInput = () => { inputRef.current.focus(); }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={focusInput}>Focus</button> </div> ); }

🔹 Store Mutable Value

const renderCount = useRef(0); useEffect(() => { renderCount.current += 1; });

Unlike state, updating useRef does NOT trigger re-render.


🛣 Routing with React Router

We use React Router to navigate between pages in a React app.


🔹 Install

npm install react-router-dom

🔹 Basic Setup

import { BrowserRouter, Routes, Route } from "react-router-dom"; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </BrowserRouter> ); }

🔹 Navigation Links

import { Link } from "react-router-dom"; function Navbar() { return ( <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> </nav> ); }

🔹 Dynamic Route Example

<Route path="/user/:id" element={<User />} />

Access param:

import { useParams } from "react-router-dom"; function User() { const { id } = useParams(); return <h1>User ID: {id}</h1>; }

🚀 Basic Project: Simple React Website

Let’s build a 3-page portfolio website.


📁 Project Structure

src/ ├── components/ │ ├── Navbar.js │ ├── Home.js │ ├── About.js │ └── Contact.js ├── App.js

🧱 Step 1: Navbar Component

import { Link } from "react-router-dom"; function Navbar() { return ( <nav style={{ display: "flex", gap: "20px" }}> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/contact">Contact</Link> </nav> ); } export default Navbar;

🏠 Step 2: Home Page

function Home() { return ( <div> <h1>Welcome to My Website</h1> <p>This is the home page.</p> </div> ); } export default Home;

📄 Step 3: About Page

function About() { return ( <div> <h1>About Me</h1> <p>I am learning React and full-stack development.</p> </div> ); } export default About;

📬 Step 4: Contact Page (Form + useState)

import { useState } from "react"; function Contact() { const [email, setEmail] = useState(""); const handleSubmit = (e) => { e.preventDefault(); alert(`Message sent from: ${email}`); }; return ( <form onSubmit={handleSubmit}> <input type="email" placeholder="Enter email" value={email} onChange={(e) => setEmail(e.target.value)} /> <button type="submit">Send</button> </form> ); } export default Contact;

🧩 Step 5: App.js

import { BrowserRouter, Routes, Route } from "react-router-dom"; import Navbar from "./components/Navbar"; import Home from "./components/Home"; import About from "./components/About"; import Contact from "./components/Contact"; function App() { return ( <BrowserRouter> <Navbar /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </BrowserRouter> ); } export default App;

🎯 What You Just Learned

✔ useState → manage state
✔ useEffect → lifecycle & side effects
✔ useRef → DOM access
✔ React Router → multi-page navigation
✔ Built a small real project


🟢 1️⃣ Introduction to Node.js

🔹 What is Node.js?

Node.js is a JavaScript runtime that allows you to run JavaScript outside the browser, mainly on the server.

It is built on Chrome’s V8 engine.

Before Node:

  • JavaScript only ran in browsers.

After Node:

  • JavaScript can power full backend servers.


🔹 Why Node.js?

  • Fast execution (V8 engine)

  • Non-blocking I/O

  • Event-driven architecture

  • Highly scalable

  • Same language (JS) for frontend & backend


🧠 Node.js Architecture

Node.js uses:

1️⃣ Single-Threaded Model

It runs on one main thread.

2️⃣ Event Loop

Handles asynchronous operations efficiently.

Instead of blocking code, Node:

  1. Receives request

  2. Delegates heavy tasks (file/db/network)

  3. Registers callback

  4. Continues handling other requests

  5. Executes callback when task completes

This is called Non-Blocking I/O.


🔹 Blocking vs Non-Blocking Example

Blocking (Bad for performance)

const fs = require("fs"); const data = fs.readFileSync("file.txt"); console.log(data.toString());

Non-Blocking (Preferred)

const fs = require("fs"); fs.readFile("file.txt", (err, data) => { console.log(data.toString()); });

Node is powerful because it doesn’t wait for one request to finish before handling another.


🚀 2️⃣ Setting Up Express.js Server

🔹 What is Express?

Express.js is a lightweight web framework for Node.js used to build APIs and web servers easily.


🔹 Step 1: Initialize Project

mkdir backend cd backend npm init -y

🔹 Step 2: Install Express

npm install express

🔹 Step 3: Create Basic Server

Create server.js:

const express = require("express"); const app = express(); app.get("/", (req, res) => { res.send("Server is running"); }); app.listen(5000, () => { console.log("Server running on port 5000"); });

Run server:

node server.js

Open:

http://localhost:5000

🛣 3️⃣ Routing in Express

Routing determines how your server responds to requests.

Basic syntax:

app.METHOD(PATH, HANDLER)

🔹 Example Routes

app.get("/users", (req, res) => { res.send("Get all users"); }); app.post("/users", (req, res) => { res.send("Create user"); }); app.put("/users/:id", (req, res) => { res.send(`Update user ${req.params.id}`); }); app.delete("/users/:id", (req, res) => { res.send(`Delete user ${req.params.id}`); });

🔹 Route Parameters

app.get("/products/:id", (req, res) => { const productId = req.params.id; res.send(`Product ID: ${productId}`); });

🔹 Query Parameters

/search?name=rahul
app.get("/search", (req, res) => { res.send(req.query.name); });

🔄 4️⃣ Middleware in Express

Middleware functions execute between request and response.

Structure:

(req, res, next)

🔹 Basic Middleware Example

app.use((req, res, next) => { console.log("Request received:", req.method); next(); // move to next middleware });

If you don’t call next(), request will hang.


🔹 Built-in Middleware

app.use(express.json()); // parse JSON app.use(express.urlencoded({ extended: true }));

🔹 Router-Level Middleware

const router = express.Router(); router.get("/", (req, res) => { res.send("User route"); }); app.use("/users", router);

🔹 Middleware Example: Authentication

function authMiddleware(req, res, next) { const token = req.headers.authorization; if (!token) { return res.status(401).send("Unauthorized"); } next(); } app.get("/dashboard", authMiddleware, (req, res) => { res.send("Protected Dashboard"); });

🏗 Recommended Backend Structure (For MERN)

backend/ ├── routes/ ├── controllers/ ├── middleware/ ├── models/ ├── config/ ├── server.js

🎯 What You Should Practice Now

Since you're building full-stack systems:

  1. Build a CRUD API

  2. Connect MongoDB

  3. Add JSON parsing

  4. Implement error handling middleware

  5. Add JWT authentication

  6. Test with Postman


🌐 1️⃣ RESTful API Design

🔹 What is REST?

REST = Representational State Transfer

It is an architectural style for designing web APIs using HTTP methods properly.


🔹 Core Principles of REST

  1. Client–Server separation

  2. Stateless communication

  3. Use HTTP methods correctly

  4. Resource-based URLs


🔹 HTTP Methods in REST

MethodPurpose
GETRetrieve data
POSTCreate data
PUTUpdate entire resource
PATCHUpdate partial resource
DELETERemove data

🔹 Good RESTful URL Design

✅ Good:

GET /users GET /users/:id POST /users PUT /users/:id DELETE /users/:id

❌ Bad:

GET /getUsers POST /createUser

Use nouns, not verbs.


🔹 Example: User API

app.get("/users", (req, res) => { res.json([{ id: 1, name: "Rahul" }]); }); app.get("/users/:id", (req, res) => { res.json({ id: req.params.id, name: "Rahul" }); }); app.post("/users", (req, res) => { res.status(201).json({ message: "User created" }); });

📦 2️⃣ Handling JSON Requests & Responses

By default, Express does NOT parse JSON unless you enable middleware.


🔹 Enable JSON Parsing

app.use(express.json());

This allows you to access:

req.body

🔹 Handling JSON Request

Client sends:

{ "name": "Rahul", "email": "rahul@gmail.com" }

Server:

app.post("/users", (req, res) => { const { name, email } = req.body; res.status(201).json({ success: true, data: { name, email } }); });

🔹 Sending JSON Response

Always use:

res.json()

Example:

res.status(200).json({ success: true, message: "Data fetched" });

🔹 Status Codes You Must Know

CodeMeaning
200OK
201Created
400Bad Request
401Unauthorized
404Not Found
500Server Error

Good APIs use correct status codes.


⚠ 3️⃣ Error Handling in Express

Errors should NOT crash your server.


🔹 Basic Error Example

app.get("/error", (req, res) => { throw new Error("Something went wrong"); });

This can crash server if not handled properly.


🔹 Centralized Error Middleware (Best Practice)

Must have 4 parameters:

app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ success: false, message: err.message }); });

Place this after all routes.


🔹 Async Error Handling

app.get("/users", async (req, res, next) => { try { const users = []; res.json(users); } catch (error) { next(error); } });

Use next(error) to forward error.


🔹 Custom Error Class (Professional Approach)

class AppError extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode; } }

Then:

return next(new AppError("User not found", 404));

🔐 4️⃣ Environment Variables & Configuration (dotenv)

Hardcoding secrets ❌
Using environment variables ✅


🔹 Install dotenv

npm install dotenv

🔹 Create .env File

PORT=5000 DB_URI=mongodb://localhost:27017/test JWT_SECRET=mysecretkey

🔹 Load dotenv (VERY IMPORTANT: at top of file)

require("dotenv").config();

🔹 Use Environment Variables

const PORT = process.env.PORT; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });

🔹 Why dotenv is Important?

  • Keeps secrets secure

  • Different config for dev/prod

  • Cleaner codebase

  • Safer deployments


🏗 Recommended Production Structure

backend/ ├── config/ │ └── db.js ├── controllers/ ├── routes/ ├── middleware/ │ └── errorMiddleware.js ├── utils/ │ └── AppError.js ├── .env ├── server.js

🎯 What You Should Practice Next

Since you're building serious full-stack systems:

  1. Build a CRUD REST API

  2. Add centralized error handler

  3. Use dotenv properly

  4. Add validation (Joi / express-validator)

  5. Implement JWT authentication

  6. Connect to MongoDB


UNIT 3

🟢 1️⃣ Introduction to NoSQL and MongoDB

🔹 What is NoSQL?

NoSQL = Non-relational database

Unlike SQL databases (MySQL, PostgreSQL):

  • No fixed schema

  • Stores data in flexible formats

  • Highly scalable

  • Better for unstructured data


🔹 Types of NoSQL Databases

  1. Document-based → MongoDB

  2. Key-value → Redis

  3. Column-based → Cassandra

  4. Graph → Neo4j


🍃 What is MongoDB?

MongoDB is a document-based NoSQL database.

Instead of tables and rows, it uses:

  • Database

  • Collections

  • Documents (JSON-like objects)


🔹 Example MongoDB Document

{ "_id": "12345", "name": "Rahul", "email": "rahul@gmail.com", "age": 25 }

Documents are stored in BSON (Binary JSON).


⚙ 2️⃣ Installing and Connecting MongoDB with Node.js

There are 2 common ways:

  • MongoDB Native Driver

  • Mongoose (Recommended for beginners & MERN)

We’ll use Mongoose.


🔹 Step 1: Install MongoDB

Download from:
👉 https://www.mongodb.com/

Or use:

  • MongoDB Atlas (Cloud)


🔹 Step 2: Install Dependencies

Inside your backend folder:

npm install mongoose

🔹 Step 3: Connect MongoDB to Node.js

Create config/db.js

const mongoose = require("mongoose"); const connectDB = async () => { try { await mongoose.connect("mongodb://127.0.0.1:27017/mydatabase"); console.log("MongoDB Connected"); } catch (error) { console.error(error); process.exit(1); } }; module.exports = connectDB;

Use in server.js

const express = require("express"); const connectDB = require("./config/db"); connectDB(); const app = express(); app.use(express.json()); app.listen(5000, () => { console.log("Server running on port 5000"); });

🏗 3️⃣ Creating a Schema & Model

MongoDB is schema-less, but Mongoose allows structure.


Create models/User.js

const mongoose = require("mongoose"); const userSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true }, age: Number }); module.exports = mongoose.model("User", userSchema);

🔄 4️⃣ CRUD Operations Using MongoDB

CRUD = Create, Read, Update, Delete


🟢 CREATE

const User = require("./models/User"); app.post("/users", async (req, res) => { try { const user = await User.create(req.body); res.status(201).json(user); } catch (error) { res.status(400).json({ error: error.message }); } });

🔵 READ (All Users)

app.get("/users", async (req, res) => { const users = await User.find(); res.json(users); });

🔵 READ (Single User)

app.get("/users/:id", async (req, res) => { const user = await User.findById(req.params.id); res.json(user); });

🟡 UPDATE

app.put("/users/:id", async (req, res) => { const updatedUser = await User.findByIdAndUpdate( req.params.id, req.body, { new: true } ); res.json(updatedUser); });

🔴 DELETE

app.delete("/users/:id", async (req, res) => { await User.findByIdAndDelete(req.params.id); res.json({ message: "User deleted" }); });

🧠 Best Practices

✔ Use async/await
✔ Wrap in try/catch
✔ Validate input
✔ Use environment variables for DB URI
✔ Separate routes/controllers


🏗 Recommended Project Structure

backend/ ├── config/ │ └── db.js ├── models/ │ └── User.js ├── routes/ │ └── userRoutes.js ├── controllers/ ├── server.js

🎯 What You Should Practice Now

Since you're building serious full-stack systems:

  1. Build full CRUD API

  2. Add validation

  3. Add error handling middleware

  4. Connect React frontend

  5. Implement authentication


Here’s a clear and practical guide to mastering Mongoose and advanced MongoDB concepts for real-world MERN apps 🚀

We’ll cover:

  • ✅ Mongoose ODM (Schemas, Models, Validation)

  • ✅ Data Relationships in MongoDB

  • ✅ Query Optimization & Aggregation Basics


🟢 1️⃣ Mongoose ODM: Schemas, Models & Validation

🔹 What is Mongoose?

Mongoose is an ODM (Object Data Modeling) library for MongoDB used with Node.js.

ODM = Bridge between MongoDB documents and JavaScript objects.

It provides:

  • Schema structure

  • Validation

  • Middleware (hooks)

  • Query building


🧱 Schemas in Mongoose

A Schema defines the structure of documents inside a collection.


🔹 Basic Schema Example

const mongoose = require("mongoose"); const userSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true }, age: { type: Number, min: 18, max: 60 }, createdAt: { type: Date, default: Date.now } });

🏗 Models in Mongoose

A Model is a wrapper around a schema.

const User = mongoose.model("User", userSchema);

Now you can:

User.find() User.create() User.findById() User.deleteOne()

✅ Validation in Mongoose

Validation ensures clean and safe data.


🔹 Built-in Validators

email: { type: String, required: true, unique: true, match: [/^\S+@\S+\.\S+$/, "Invalid email format"] }

🔹 Custom Validation

age: { type: Number, validate: { validator: function(value) { return value >= 18; }, message: "Age must be 18 or above" } }

🔹 Handling Validation Errors

try { await User.create(req.body); } catch (error) { res.status(400).json({ message: error.message }); }

🔄 2️⃣ Data Relationships in MongoDB

MongoDB is NoSQL, but relationships are still possible.

Two main approaches:


🟢 1. Embedding (Denormalization)

Store related data inside a document.

Example: Blog with Comments

const blogSchema = new mongoose.Schema({ title: String, comments: [ { text: String, author: String } ] });

✔ When to Use:

  • Small related data

  • Data always fetched together


🔵 2. Referencing (Normalization)

Store reference IDs.


Example: User & Post Relationship

const postSchema = new mongoose.Schema({ title: String, content: String, user: { type: mongoose.Schema.Types.ObjectId, ref: "User" } });

🔹 Using populate()

const posts = await Post.find().populate("user");

populate() replaces ObjectId with actual user document.


✔ When to Use Referencing:

  • Large data

  • Many-to-many relationships

  • Data queried separately


🔷 Relationship Types

TypeExample
One-to-OneUser → Profile
One-to-ManyUser → Posts
Many-to-ManyStudents ↔ Courses

⚡ 3️⃣ Query Optimization Basics

As your database grows, performance matters.


🟢 1. Indexing

Indexes make queries faster.

userSchema.index({ email: 1 });

Common fields to index:

  • email

  • username

  • foreign keys

  • frequently searched fields

⚠ Over-indexing slows writes.


🔵 2. Use Select to Limit Fields

User.find().select("name email");

Fetch only needed fields → faster queries.


🔵 3. Pagination

Avoid loading thousands of records.

const users = await User.find() .skip(10) .limit(10);

Better approach for large data:

  • Cursor-based pagination


📊 4️⃣ Aggregation Basics

Aggregation is used for:

  • Analytics

  • Reports

  • Grouping

  • Summaries

MongoDB uses Aggregation Pipeline.


🔹 Basic Aggregation Example

Count users by age:

const result = await User.aggregate([ { $group: { _id: "$age", count: { $sum: 1 } } } ]);

🔹 Common Aggregation Stages

StagePurpose
$matchFilter data
$groupGroup data
$sortSort results
$projectSelect fields
$lookupJoin collections

🔹 Example: Join Users & Posts

const result = await Post.aggregate([ { $lookup: { from: "users", localField: "user", foreignField: "_id", as: "userDetails" } } ]);

🧠 Real-World Optimization Tips

✔ Use indexes wisely
✔ Avoid large document embedding
✔ Use pagination
✔ Select only needed fields
✔ Use aggregation for reports
✔ Monitor slow queries


🏗 Professional Backend Structure

backend/ ├── models/ ├── controllers/ ├── routes/ ├── middleware/ ├── utils/ └── config/

🎯 What You Should Build Next

Since you're building serious full-stack systems:

  1. Blog system (Users + Posts + Comments)

  2. E-commerce backend (Products + Orders)

  3. Authentication + role-based access

  4. Analytics dashboard using aggregation


UNIT 4

Here’s a complete full-stack guide to connecting React with Express/MongoDB and implementing JWT authentication 🚀

We’ll cover:

1️⃣ Connecting React frontend with Express backend
2️⃣ Axios / Fetch for HTTP requests
3️⃣ JWT-based authentication & authorization


🔗 1️⃣ Connecting React Frontend with Express + MongoDB Backend

Your architecture:

React (Frontend) → Express (Backend API) → MongoDB (Database)

Frontend sends HTTP requests → Backend handles logic → MongoDB stores data → Response sent back.


🟢 Backend Setup Example

Assume backend running on:

http://localhost:5000

Enable JSON + CORS:

npm install cors
const express = require("express"); const cors = require("cors"); const app = express(); app.use(cors()); app.use(express.json()); app.get("/api/users", (req, res) => { res.json([{ name: "Rahul" }]); }); app.listen(5000);

🟢 Frontend Setup (React)

Your React app runs on:

http://localhost:3000

Now we fetch data from backend.


🌐 2️⃣ Axios or Fetch API for HTTP Requests

You can use:

  • Native fetch()

  • Or Axios (more popular in production)


🔵 Option 1: Using Fetch API

import { useEffect, useState } from "react"; function Users() { const [users, setUsers] = useState([]); useEffect(() => { fetch("http://localhost:5000/api/users") .then(res => res.json()) .then(data => setUsers(data)); }, []); return ( <div> {users.map((user, index) => ( <p key={index}>{user.name}</p> ))} </div> ); }

🔵 Option 2: Using Axios (Recommended)

Install:

npm install axios

Example:

import axios from "axios"; import { useEffect, useState } from "react"; function Users() { const [users, setUsers] = useState([]); useEffect(() => { axios.get("http://localhost:5000/api/users") .then(res => setUsers(res.data)) .catch(err => console.error(err)); }, []); return ( <div> {users.map((user, index) => ( <p key={index}>{user.name}</p> ))} </div> ); }

🔥 Best Practice: Create Axios Instance

// api.js import axios from "axios"; const API = axios.create({ baseURL: "http://localhost:5000/api" }); export default API;

Now use:

API.get("/users");

Cleaner and scalable.


🔐 3️⃣ JWT-Based Authentication & Authorization

JWT = JSON Web Token

Used for:

  • Login authentication

  • Protecting routes

  • Role-based access

Library: jsonwebtoken


🟢 Step 1: Install Backend Dependencies

npm install jsonwebtoken bcryptjs
  • bcryptjs → hash passwords

  • jsonwebtoken → generate tokens


🧱 Step 2: User Model (MongoDB)

const mongoose = require("mongoose"); const userSchema = new mongoose.Schema({ name: String, email: String, password: String, role: { type: String, default: "user" } }); module.exports = mongoose.model("User", userSchema);

🔐 Step 3: Register Route

const bcrypt = require("bcryptjs"); app.post("/api/register", async (req, res) => { const { name, email, password } = req.body; const hashedPassword = await bcrypt.hash(password, 10); const user = await User.create({ name, email, password: hashedPassword }); res.status(201).json(user); });

🔐 Step 4: Login Route (Generate JWT)

const jwt = require("jsonwebtoken"); app.post("/api/login", async (req, res) => { const { email, password } = req.body; const user = await User.findOne({ email }); if (!user) return res.status(400).json({ message: "User not found" }); const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) return res.status(400).json({ message: "Invalid password" }); const token = jwt.sign( { id: user._id, role: user.role }, process.env.JWT_SECRET, { expiresIn: "1d" } ); res.json({ token }); });

🛡 Step 5: Auth Middleware (Protect Routes)

const authMiddleware = (req, res, next) => { const token = req.headers.authorization; if (!token) return res.status(401).json({ message: "Unauthorized" }); try { const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = decoded; next(); } catch (error) { res.status(401).json({ message: "Invalid token" }); } };

🔐 Protected Route Example

app.get("/api/profile", authMiddleware, (req, res) => { res.json({ message: "Welcome", user: req.user }); });

🌐 4️⃣ Sending Token from React

After login:

localStorage.setItem("token", res.data.token);

Send token in requests:

API.get("/profile", { headers: { Authorization: localStorage.getItem("token") } });

🔒 Role-Based Authorization (Admin Example)

const adminOnly = (req, res, next) => { if (req.user.role !== "admin") { return res.status(403).json({ message: "Access denied" }); } next(); };

🏗 Full Production Flow

  1. User registers

  2. Password hashed

  3. User logs in

  4. JWT generated

  5. Token stored in frontend

  6. Token sent with every request

  7. Backend verifies token

  8. Access granted/denied


⚠ Production Best Practices

✔ Store JWT_SECRET in .env
✔ Use HTTPS
✔ Add token expiration
✔ Implement refresh tokens
✔ Never store plain passwords
✔ Use centralized error handling


🎯 What You Should Build Now

Since you're building serious systems, try:

  1. Full authentication system

  2. Role-based access control (Admin/User)

  3. Protected React routes

  4. Profile dashboard with JWT

  5. Logout functionality


Here’s a complete full-stack production guide covering deployment, state management, structure, and real-time updates 🚀

We’ll cover:

1️⃣ Deployment strategies (Heroku, Vercel, Netlify)
2️⃣ State management (Redux vs Context API)
3️⃣ Project structure & best practices
4️⃣ Optional: Real-time updates with Socket.io


🚀 1️⃣ Deployment Strategies

🌍 Frontend Deployment

🔹 1. Vercel (Best for React)

Vercel

✅ Zero config
✅ Automatic GitHub deployments
✅ Fast global CDN
✅ Great for React & Next.js

Steps:

  1. Push code to GitHub

  2. Import project in Vercel

  3. Deploy

Set environment variables in dashboard.


🔹 2. Netlify

Netlify

Great alternative for static React apps.

Build settings:

Build command: npm run build Publish directory: build

🌍 Backend Deployment

🔹 3. Heroku (Traditional Option)

Heroku

Good for Node.js backend hosting.

Steps:

  • Add Procfile

  • Use environment variables

  • Deploy via Git

Example Procfile:

web: node server.js

🔥 Modern Backend Alternatives

  • Render

  • Railway

  • Fly.io


🗂 Full MERN Deployment Architecture

Frontend (Vercel) ↓ Backend (Render / Heroku) ↓ MongoDB Atlas (Cloud DB)

Use:

  • MongoDB Atlas connection string

  • Environment variables for secrets


🧠 2️⃣ State Management (Redux vs Context API)

When apps grow, passing props becomes messy → Use state management.


🔵 Option 1: Context API (Built-in React)

Part of React

Good for:

  • Small to medium apps

  • Theme, Auth, User state


🔹 Create Context

import { createContext, useState } from "react"; export const AuthContext = createContext(); export function AuthProvider({ children }) { const [user, setUser] = useState(null); return ( <AuthContext.Provider value={{ user, setUser }}> {children} </AuthContext.Provider> ); }

Use in component:

const { user } = useContext(AuthContext);

✔ When to Use Context?

  • Authentication

  • Dark/light mode

  • Global settings


🔴 Option 2: Redux (Large Apps)

Redux

Best for:

  • Complex global state

  • Large enterprise apps

  • Many reducers

Install:

npm install @reduxjs/toolkit react-redux

🔹 Basic Redux Example

import { configureStore, createSlice } from "@reduxjs/toolkit"; const counterSlice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: state => { state.value += 1; } } }); export const { increment } = counterSlice.actions; export const store = configureStore({ reducer: counterSlice.reducer });

Wrap app:

<Provider store={store}> <App /> </Provider>

🆚 Redux vs Context

FeatureContextRedux
ComplexitySimpleAdvanced
BoilerplateLowMedium
PerformanceMediumHigh
Large apps❌✅

👉 For most MERN apps:
Start with Context → Move to Redux if needed.


🏗 3️⃣ Project Structure & Best Practices

🔹 Frontend Structure

src/ ├── components/ ├── pages/ ├── hooks/ ├── context/ ├── redux/ ├── services/ ← API calls ├── utils/ ├── App.js

🔹 Backend Structure

backend/ ├── config/ ├── controllers/ ├── middleware/ ├── models/ ├── routes/ ├── utils/ ├── server.js

🔥 Best Practices

✔ Use environment variables
✔ Use centralized error handling
✔ Separate business logic (controllers)
✔ Use async/await
✔ Validate input
✔ Use proper HTTP status codes
✔ Keep frontend and backend separate
✔ Never expose secrets in frontend


⚡ 4️⃣ Optional: Real-Time Updates with Socket.io

For:

  • Chat apps

  • Notifications

  • Live dashboards

  • Online gaming

Library: Socket.IO


🔹 Backend Setup

npm install socket.io
const server = require("http").createServer(app); const io = require("socket.io")(server); io.on("connection", socket => { console.log("User connected"); socket.on("message", msg => { io.emit("message", msg); }); });

🔹 Frontend Setup

npm install socket.io-client

import { io } from "socket.io-client"; const socket = io("http://localhost:5000"); socket.emit("message", "Hello World"); socket.on("message", msg => { console.log(msg); });
🔥 Real-Time Architecture
Client 1 ←→ Socket Server Client 2 ←→




🎯 What You Should Build Now Based on your full-stack progress, try: 🔐 Auth system with JWT 📊 Admin dashboard with Redux 💬 Real-time chat app (Socket.io) 🚀 Deploy full MERN app to production







No comments:

Post a Comment

02

Capstone resource hub

Codingacharya

Capstone Learning Resources, Notes & Project Hub

TCS NQT Questions
Read Notes
Machine Learning – ACE Theory
Read Notes
Machine Learning PPT
Read Notes
MachienLearning LAB
Read Notes
CSPT LAB programs
Read Notes
Time table and CSPT syllabus
Read Notes
Appreciations
Read Notes
ISTE life memberships
Read Notes
Artificial Intelligence & Analytics
Read Notes
Fullstack Web Dev
Read Notes
MERN Web Dev
Read Notes
Course Structure
Read Notes
Cloud Computing
Read Notes
90 Days ML Challenge
Read Notes
Advanced Analytics & Viz
Read Notes
Advanced Machine Learning
Read Notes
React JS
Read Notes
ML Chaitanya
Read Notes
Important Links
Read Notes
CSS Effects
Read Notes
RESUME
Read Notes
Bootstrap CSS
Read Notes
MongoDB
Read Notes
OWN Python Package
Read Notes
HTML Course
Read Notes
HTML Projects
Read Notes
GitHub Projects
Read Notes
Angular JS
Read Notes
Journals
Read Notes
NLP Notes
Read Notes
Videos
Read Notes
Data Analytics & Viz
Read Notes
Cloud Computing (Archive)
Read Notes
Open CV
Read Notes
jQuery
Read Notes
React JS (Archive)
Read Notes
Node JS
Read Notes
DAV Theory
Read Notes
DAV Lab
Read Notes
Big Data Notes
Read Notes
R-Programming
Read Notes
HADOOP Lab
Read Notes
GATE DA
Read Notes
JAVA Lab
Read Notes
Computer Networks
Read Notes
03

Live projects & profiles