Skip to content
BCA-442E · Advanced Web Development Technologies
Unit 3

Node.js and Express.js Server-Side Engineering

Sign in to save
Unit 3 Learning Hub

Node.js and Express.js Server-Side Engineering

Core Definitions & Key Concepts

Core Definitions & Key Concepts

What is Node.js and what is its underlying engine

Node.js is an open-source, cross-platform, single-threaded asynchronous runtime environment built on Google Chrome's V8 JavaScript engine and libuv, enabling JavaScript execution on backend servers.

What is libuv in Node.js

A multi-platform C library that provides Node.js with support for asynchronous I/O based on an event loop, non-blocking networking, and a background thread pool for handling blocking system operations (file system, DNS, crypto).

Non-Blocking I/O in Node.js

When an I/O operation (reading a file, querying a database) is initiated, Node.js does not block the single main execution thread. Instead, it delegates the operation to libuv/OS kernel and immediately continues executing subsequent code, firing a callback upon I/O completion.

What is the Node Package Manager (NPM)

The default package manager and software registry for Node.js, managing project dependencies, versioning (package.json, package-lock.json), and executable task scripts.

CommonJS (require) and ES Modules (import)

  • CommonJS (CJS): Synchronous loading mechanism standard in legacy Node.js (const express = require('express'); module.exports = app;).
  • ES Modules (ESM): Asynchronous static import standard in modern JavaScript (import express from 'express'; export default app;).

What is the EventEmitter class in Node.js

A core module (events) providing the basis for Node's event-driven architecture. Objects emit named events that cause previously registered listener functions to be invoked (emitter.on('event', callback)).

What are Node.js Streams and what are their 4 primary types

Objects that allow reading data from or writing data to a continuous flow without loading the entire payload into RAM at once. Types: Readable, Writable, Duplex, and Transform.

What is Express.js

A fast, unopinionated, minimalist web framework for Node.js that provides a robust suite of features for building single-page, multi-page, and hybrid REST API web applications.

Middleware in Express.js

Functions that have access to the Request object (req), Response object (res), and the next function in the application’s request-response cycle, capable of executing code, modifying request objects, ending cycles, or invoking the next middleware.

What is the purpose of the next() function in Express middleware

Passes control to the next middleware function in the execution stack. If next() is not called and the response is not terminated (res.send()), the client request is left hanging.

✓Topic 1 covered: Core Definitions & Key Concepts
Next: Conceptual & Architectural Analysis↓

Conceptual & Architectural Analysis

Conceptual & Architectural Analysis

The Node.js Event Loop Architecture (The 6 Distinct Phases)

Libuv Event Loop Phases

System Architecture / Concept DiagramHorizontal Scroll Enabled
   +---------------------------------------------+
   | Timers: setTimeout, setInterval             |
   +----------------------+----------------------+
                          |
   +----------------------v----------------------+
   | Pending Callbacks: I/O callbacks deferred    |
   +----------------------+----------------------+
                          |
   +----------------------v----------------------+
   | Idle, Prepare: Internal libuv house-keeping  |
   +----------------------+----------------------+
                          |
   +----------------------v----------------------+
   | Poll: Retrieve new I/O events, execute I/O  |
   +----------------------+----------------------+
                          |
   +----------------------v----------------------+
   | Check: setImmediate() callbacks execute     |
   +----------------------+----------------------+
                          |
   +----------------------v----------------------+
   | Close Callbacks: socket.on('close')         |
   +---------------------------------------------+
  • Between every phase transition, Node.js completely drains the Microtask Queue (process.nextTick() and Promise resolutions).

Detail the Types of Middleware in Express.js

Express Middleware Taxonomy

  1. Application-Level Middleware: Bound to app.use() or app.METHOD() (e.g., global logging app.use(morgan('combined'))).
  2. Router-Level Middleware: Bound to an instance of express.Router() (e.g., scoping authentication strictly to /api/v1/admin routes).
  3. Error-Handling Middleware: Defined strictly with 4 arguments: (err, req, res, next). Centralizes global error formatting.
  4. Built-in Middleware: Bundled with Express (express.json(), express.urlencoded(), express.static()).
  5. Third-Party Middleware: Installed via NPM (cors, helmet, cookie-parser).

Stream Piping and Backpressure Handling in Node.js

Stream Piping & Backpressure Mechanics

System Architecture / Concept DiagramHorizontal Scroll Enabled
[ Readable Stream: Large 10GB Video File ]
                   |
                   v  (Data chunks stream at 100MB/s)
          .pipe(writableStream)
                   |
                   v
[ Writable Stream: Slow Network Socket (Processes at 10MB/s) ]
  • Backpressure Problem: When read rate drastically exceeds write rate, data accumulates in RAM buffer, leading to process crash via Out-of-Memory (OOM).
  • The Solution: Calling readable.pipe(writable) automatically handles backpressure: when the writable stream's internal buffer exceeds highWaterMark, writable.write() returns false, pausing the readable stream until the writable stream emits the 'drain' event.

Detail RESTful API Architecture with Express Router Modularization

Modular Express Directory Structure

  • server.js: Instantiates Express app, connects database, applies global security middleware (Helmet, CORS), mounts route prefixes.
  • routes/courses.routes.js: Defines route paths (/courses, /:id) mapping to controller methods.
  • controllers/courses.controller.js: Business logic coordinating database queries and responding with JSON DTOs.
  • middleware/auth.middleware.js: Validates JWT Bearer tokens in headers, attaching decoded user identities to req.user.

Compare Node.js Single-Threaded Event Loop vs Multi-Threaded Web Servers (Apache/Java Tomcat)

DimensionNode.js (Asynchronous Event Loop)Traditional Multi-Threaded (Apache/Tomcat)
Concurrency ModelSingle main thread; non-blocking async I/OOne operating system thread per client connection
Memory per ClientUltra-low (~2KB per connection state)High (1MB–2MB stack allocated per thread)
Concurrent LimitsTens of thousands of concurrent connectionsCapped by physical thread pool memory limits
CPU-Intensive TasksVulnerable to blocking the main event loopIsolated across independent CPU worker threads
Best Used ForReal-time I/O, REST APIs, WebSockets, streamingHeavy computational processing, video encoding
✓Topic 2 covered: Conceptual & Architectural Analysis
Next: In-Depth Analysis & Implementation↓

In-Depth Analysis & Implementation

In-Depth Analysis & Implementation

Provide an In-Depth Architectural Guide to Building an Enterprise Production REST API in Node.js and Express with JWT Authentication, Security Headers, and Centralized Error Handling

Enterprise Express REST Architecture

System Architecture / Concept DiagramHorizontal Scroll Enabled
import express from 'express';
import helmet from 'helmet';
import cors from 'cors';
import rateLimit from 'express-rate-limit';

const app = express();

// 1. Enterprise Security Hardening
app.use(helmet()); // Sets HTTP security headers (CSP, HSTS, X-Frame-Options)
app.use(cors({ origin: 'https://xrounder.com', credentials: true }));
app.use(express.json({ limit: '10kb' })); // Prevents large payload DoS attacks

// 2. Distributed Rate Limiter
const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // 100 requests per IP
    message: { error: 'Too many requests, please try again later.' }
});
app.use('/api/', limiter);

// 3. Centralized Asynchronous Error-Wrapping Middleware
const asyncHandler = (fn) => (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
};

// 4. Sample Authenticated Route Controller
app.get('/api/v1/profile', asyncHandler(async (req, res) => {
    const authHeader = req.headers.authorization;
    if (!authHeader?.startsWith('Bearer ')) {
        const err = new Error('Unauthorized');
        err.statusCode = 401;
        throw err;
    }
    res.json({ status: 'success', data: { user: 'Student BCA' } });
}));

// 5. Centralized Global Error Handler Middleware
app.use((err, req, res, next) => {
    const statusCode = err.statusCode || 500;
    res.status(statusCode).json({
        status: 'error',
        message: err.message || 'Internal Server Error',
        ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
    });
});

export default app;

Node.js Cluster Module and Worker Threads for CPU-Bound Computational Scaling

Multi-Core Scaling in Node.js

1. Cluster Module (Process-Level Forking)

  • Node.js runs on a single CPU core by default. On a 16-core server, 15 cores sit idle.
  • Cluster Mode: Master process uses child_process.fork() to spawn N independent worker processes (typically matching CPU core count).
  • Master process listens on the network port (e.g., port 8080) and distributes incoming TCP connections among workers using a Round-Robin load balancing algorithm.

2. Worker Threads (worker_threads module)

  • Introduced in Node.js 10.5 for CPU-intensive tasks (image processing, cryptographic hashing, matrix calculations) that would otherwise block the main event loop.
  • Unlike Cluster (which creates separate processes with isolated memory), Worker Threads run in the same process sharing memory via SharedArrayBuffer, passing messages via postMessage() without process overhead.

Critically Analyze Node.js Security Pitfalls: Event Loop Starvation, ReDoS (Regular Expression Denial of Service), and Prototype Pollution

Advanced Node.js Security Threat Modeling

1. Event Loop Starvation

  • Executing synchronous long loops (while(true), heavy JSON stringify on 50MB files) blocks the single event loop thread, causing timeouts for all concurrent users.

2. ReDoS (Regular Expression Denial of Service)

  • Vulnerable regular expressions with catastrophic backtracking (e.g., ^(a+)+$ evaluated against aaaaaaaaaaaaaaaaaaaaX) exhibit O(2^n) exponential complexity, pinning CPU at 100%.

3. Prototype Pollution

  • Occurs when recursive object merge functions unsafely copy properties into target[key]. If key is __proto__, the attacker injects properties directly into Object.prototype, altering behavior of all objects across the entire Node.js runtime.
✓Topic 3 covered: In-Depth Analysis & Implementation
Next: Important Exam Points & Quick Revision↓

Important Exam Points & Quick Revision

Important Exam Points & Quick Revision

Examiners frequently evaluate: Node.js Event Loop phases and libuv (10/15 marks), Express middleware concept and next() (5/10 marks), and Streams vs Buffers with backpressure (5 marks).

Practice Ready

Ready to practice Unit 3?

You've read the core concepts. Take the balanced 10-question practice set to test your mastery!

Save progress