Backend is the server that handles:
- Data storage (database)
- Business logic (calculations, validations)
- Authentication (login, security)
- API endpoints (where frontend sends requests)
Your project uses Node.js + Express for backend.
REST API = Way for frontend to talk to backend
GET /api/users → Fetch data
POST /api/auth/login → Create data (submit form)
PUT /api/users/123 → Update data
DELETE /api/users/123 → Delete data
FRONTEND BACKEND
↓ ↑
Sends HTTP Request ← Receives Request
{ ↓
method: POST Processes Data
url: /api/auth/login ↓
body: {email, password} Database Operation
} ↓
↑ Sends JSON Response
Gets JSON Response ↓
{
token: "xyz",
user: { name, email }
}
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cors from "cors";
const app = express();
// Middleware: Process incoming requests
app.use(express.json()); // Parse JSON requests
app.use(cors()); // Allow frontend to call this API
// Routes: Define what endpoints do
app.use("/api/auth", auth); // Login/register
app.use("/api/details", detailed); // Fetch details
app.use("/api/judge", judge); // Judge operations
app.use("/api/upload", uploadRoutes); // File upload
// Start server
const port = process.env.PORT || 4000;
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});What's happening:
- Import express (framework for APIs)
- Set up middleware (express.json, cors)
- Define routes (endpoints)
- Start server on port 4000
Middleware = Code that processes requests before reaching the endpoint
Request comes in
↓
Middleware 1 (express.json) → Parse JSON
↓
Middleware 2 (cors) → Check if allowed
↓
Middleware 3 (auth) → Verify user token
↓
Route Handler → Do the actual work
↓
Send Response
app.use(express.json());
// Parses incoming JSON
// Converts JSON string to JavaScript object
app.use(cors());
// Allows frontend domain to call backend
// Without this: frontend can't make requests
app.use("/api/auth", auth);
// Routes all /api/auth/* requests to auth.jsRoutes are like functions that run when you visit a URL.
// When frontend does: POST /api/auth/login
// This code runs:
app.post("/api/auth/login", async (req, res) => {
const { email, password } = req.body; // Get from request
// Check password
const user = await User.findOne({ email });
if (!user) {
return res.status(404).json({ error: "User not found" });
}
// Send response
res.json({
token: "xyz...",
user: { name: user.name, email: user.email }
});
});What's happening:
- Frontend sends
POST /api/auth/loginwith email and password - Backend receives request in
req - Backend checks database
- Backend sends response with
res.json()
POST /api/auth/register → Create new user account
POST /api/auth/login → Login user, get token
GET /api/auth/profile → Get current user infoGET /api/details/:id → Get user/team detailsPOST /api/judge/score → Submit judge score
GET /api/judge/results → Get judge resultsPOST /api/upload → Upload image/fileFrontend Code:
// In React component
async function login(email, password) {
const response = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password })
});
const data = await response.json();
// data = { token: "xyz", user: {...} }
localStorage.setItem("token", data.token); // Save token
}Backend Code:
// In auth.js
app.post("/api/auth/login", async (req, res) => {
const { email, password } = req.body;
// Verify credentials
const user = await User.findOne({ email });
const validPassword = bcrypt.compare(password, user.password);
if (validPassword) {
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET);
res.json({ token, user });
} else {
res.status(401).json({ error: "Invalid password" });
}
});❌ Don't store plain passwords:
// BAD
user.password = "mypassword123"; // If hacked, passwords exposed!✅ Hash passwords:
// GOOD
const hashedPassword = bcrypt.hash("mypassword123");
// Hashing: "mypassword123" → "aG7k2jH3m9x0..."
// Cannot reverse it!Token = Proof that user is logged in
User logs in
↓
Backend creates token with user ID
↓
Frontend stores token (localStorage)
↓
Future requests include token
↓
Backend verifies token
↓
Serves data if token valid
Token Example:
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2M2FmMTIzIn0...
Contains: { userId: "63af123" }
Signed with: process.env.JWT_SECRET
Backend can verify it wasn't tampered with
Your backend uses MongoDB via Mongoose.
// models/auth.js
const userSchema = new Schema({
fullName: String,
email: String,
password: String, // Hashed!
createdAt: Date
});
const User = mongoose.model("User", userSchema);
// Insert user
const newUser = new User({ fullName, email, password });
await newUser.save();
// Find user
const user = await User.findOne({ email });
// Update user
await User.updateOne({ _id: id }, { fullName: "New Name" });
// Delete user
await User.deleteOne({ _id: id });Backend validates again even though frontend did:
// Frontend validates with Zod
// Backend validates with database checks
app.post("/api/auth/register", async (req, res) => {
const { email, password } = req.body;
// Check if user already exists
const existing = await User.findOne({ email });
if (existing) {
return res.status(400).json({ error: "Email already registered" });
}
// Create user
const newUser = new User({ email, password: bcrypt.hash(password) });
await newUser.save();
res.json({ message: "User registered" });
});Why? Frontend can be bypassed, backend is more secure.
Answer:
"REST API is a way for frontend and backend to communicate. Frontend sends HTTP requests (GET, POST, PUT, DELETE) to endpoints. Backend responds with JSON data. Example: POST /api/auth/login with email/password."
Answer:
"Middleware processes requests before they reach the route handler. Examples: express.json() parses JSON, cors() allows frontend to call backend. Middleware runs in order and can stop the request."
Answer:
"Hashing converts password to unreadable string. If database is hacked, passwords are protected because hashes can't be reversed. bcrypt is a hashing library that makes this secure."
Answer:
"JWT is a token given after login. It contains user ID and is signed by backend. Frontend stores it and sends with future requests. Backend verifies the signature to confirm token is valid."
✅ Backend = Server handling logic and data ✅ REST API = HTTP methods (GET, POST, PUT, DELETE) ✅ Middleware = Process requests before routes ✅ Routes = Endpoints that do specific work ✅ Authentication = Passwords hashed, tokens for sessions ✅ Database = Stores and retrieves data
Next: Read 04_DATABASE.md to understand data storage.