Siksha Sarovar

Siksha Sarovar (sikshasarovar.com) is a free educational web application that helps students in India learn programming and prepare for academic and competitive exams. The platform offers structured coding courses (C, C++, Python, Java, HTML, CSS, PHP, Power BI, AI, Machine Learning, Data Science), complete university curriculum notes for BCA/MCA students with previous year question papers, Class 10 and Class 12 CBSE/HBSE school notes, and dedicated preparation material for SSC, UPSC, Banking, Railway and other government exams. Browsing the site is completely free and requires no account. Users may optionally sign in with Google solely to save their learning progress, quiz scores and personal preferences across devices.

Privacy Policy | Terms of Service | Contact Siksha Sarovar | About Siksha Sarovar

v4.0.9 · PWA
Siksha Sarovar logo
Siksha Sarovar
Your Learning Universe

Siksha Sarovar is a free e-learning platform for coding courses, BCA university notes and competitive exam preparation. Optional Google sign-in saves your learning progress across devices.

Initializing knowledge base…
Compiling modules 0%

12. Complete Guide for Router and Controller with Debugging

Lesson 12 of 23 in the free Backend Development notes on Siksha Sarovar, written by Rohit Jangra.

Express Router — Why Use It

When all your routes are in a single app.js file, the file quickly becomes thousands of lines long and unmaintainable. Express Router allows you to split routes into separate files based on resource or feature, then mount them in app.js.

Benefits:

  • Separation of concerns: user routes, video routes, auth routes in separate files
  • Modularity: each route file is independently testable
  • Cleaner app.js: just mounts routers, no individual route definitions
  • Middleware scoping: apply middleware only to specific routers

---

Controller Pattern

A controller is a function that handles a specific route. Following the Single Responsibility Principle, each controller does exactly one thing. Controllers should:

  1. Extract data from request (body, params, query)
  2. Validate inputs
  3. Call service/model layer
  4. Send response

---

Route Parameters, Query Strings, and Body

// Route parameter: /api/users/:id
// Access via: req.params.id
router.get('/users/:id', getUser);

// Query string: /api/videos?page=1&limit=10&sortBy=views
// Access via: req.query.page, req.query.limit, req.query.sortBy
router.get('/videos', getVideos);

// Request body: POST /api/users { name, email, password }
// Access via: req.body.name, req.body.email
// Requires: app.use(express.json())
router.post('/users', createUser);

---

express.json() and express.urlencoded()

These two middleware functions are essential:

app.use(express.json());                           // Parse JSON body
app.use(express.urlencoded({ extended: true }));   // Parse form data

Without express.json(), req.body will be undefined for JSON POST requests. Without express.urlencoded(), HTML form submissions will not be parsed.

---

Morgan Logger Setup

Morgan logs every incoming HTTP request — method, URL, status code, response time:

npm install morgan
import morgan from 'morgan';
app.use(morgan('dev'));
// Output: GET /api/users 200 45.123 ms - 256
// Formats: 'dev', 'combined', 'common', 'short', 'tiny'

---

Debugging Techniques

1. console.log req.body/params/query:

const createUser = asyncHandler(async (req, res) => {
  console.log('req.body:', req.body);
  console.log('req.params:', req.params);
  console.log('req.query:', req.query);
  console.log('req.headers:', req.headers);
  // ... rest of controller
});

2. Postman debugging:

  • Create a Collection for your API
  • Create Environment with {{baseUrl}} = http://localhost:5000
  • Set Content-Type: application/json in request headers
  • Check Response Body, Status, Headers, and Cookies
  • Use Postman Console (View → Console) to see request details

3. Reading stack traces: When your server throws an error, the stack trace shows which file and line caused it. Always read from top to bottom — the first line after "Error:" shows the actual problem.

---

Route Ordering Importance

Express matches routes in the order they are defined. Specific routes must come before generic ones:

// ✅ Correct order:
router.get('/users/me', getMe);          // Specific — matches first
router.get('/users/:id', getUserById);   // Generic — matches :id

// ❌ Wrong order:
router.get('/users/:id', getUserById);   // 'me' would match as id='me'
router.get('/users/me', getMe);          // Never reached

---

Complete User Routes and Controller Example

userRoutes.js:

import { Router } from 'express';
import {
  getAllUsers, createUser, getUserById,
  updateUser, deleteUser
} from '../controllers/user.controller.js';
import { verifyJWT } from '../middlewares/auth.middleware.js';

const router = Router();

router.route('/').get(getAllUsers).post(createUser);
router.route('/:id')
  .get(verifyJWT, getUserById)
  .put(verifyJWT, updateUser)
  .delete(verifyJWT, deleteUser);

export { router as userRouter };

Mount in app.js:

app.use('/api/v1/users', userRouter);
// Now: GET /api/v1/users, POST /api/v1/users, GET /api/v1/users/:id, etc.