0% found this document useful (0 votes)
9 views142 pages

Nodejs Expressjs Complete Notes - MD

This document is a comprehensive guide to backend development using Node.js and Express.js, covering essential topics such as Node.js fundamentals, package management with NPM, and best practices. It includes detailed explanations, code examples, and common mistakes to avoid in various aspects of Node.js development. The guide serves as a valuable resource for developers looking to enhance their skills in building server-side applications.

Uploaded by

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

Nodejs Expressjs Complete Notes - MD

This document is a comprehensive guide to backend development using Node.js and Express.js, covering essential topics such as Node.js fundamentals, package management with NPM, and best practices. It includes detailed explanations, code examples, and common mistakes to avoid in various aspects of Node.js development. The guide serves as a valuable resource for developers looking to enhance their skills in building server-side applications.

Uploaded by

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

Complete [Link] and Express.

js Notes
A Comprehensive Guide to Backend Development with [Link] and [Link]

Table of Contents
1. Introduction to [Link]
2. [Link] Fundamentals
3. NPM and Package Management
4. File System Operations
5. Asynchronous Programming
6. Streams and Buffers
7. Events and Event Emitters
8. HTTP Module
9. [Link] Introduction
10. Express Routing
11. Middleware
12. Request and Response Objects
13. Template Engines
14. Error Handling
15. Database Integration
16. Authentication and Authorization
17. RESTful API Design
18. Security Best Practices
19. Testing
20. Performance Optimization
21. Deployment

1. Introduction to [Link]
Theory
What is [Link]?
[Link] is a JavaScript runtime built on Chrome's V8 JavaScript engine
It allows JavaScript to run on the server-side
Non-blocking, event-driven architecture
Single-threaded with event loop for handling concurrent operations
Uses CommonJS module system (now also supports ES modules)
Key Characteristics:
Asynchronous & Non-blocking I/O: Operations don't block the execution thread
Event-Driven: Uses events to trigger callbacks
Fast Execution: V8 engine compiles JavaScript to native machine code
NPM Ecosystem: Largest package ecosystem in the world
Cross-Platform: Runs on Windows, Linux, macOS

Use Cases:
RESTful APIs and microservices
Real-time applications (chat, gaming, collaboration tools)
Streaming applications
Single Page Applications (SPAs)
Command-line tools
IoT applications

Not Ideal For:


CPU-intensive tasks (image processing, video encoding)
Heavy computational tasks
Applications requiring complex server-side rendering with blocking operations

Code Example

javascript
// Basic [Link] script
[Link]('Hello from [Link]!');

// Check [Link] version


[Link](`[Link] version: ${[Link]}`);

// Environment information
[Link](`Platform: ${[Link]}`);
[Link](`Architecture: ${[Link]}`);

// Process information
[Link](`Process ID: ${[Link]}`);
[Link](`Current directory: ${[Link]()}`);

// Command line arguments


[Link](`Arguments: ${[Link]}`);

// Environment variables
[Link](`NODE_ENV: ${[Link].NODE_ENV}`);

Mistakes to Avoid
❌ Mistake 1: Thinking [Link] is multi-threaded

javascript

// Wrong assumption: This won't create new threads automatically


for (let i = 0; i < 1000000; i++) {
// CPU-intensive task blocks everything
}

✅ Correct: Use worker threads for CPU-intensive tasks

javascript

const { Worker } = require('worker_threads');

const worker = new Worker('./[Link]');


[Link]('message', (result) => {
[Link]('Result:', result);
});

❌ Mistake 2: Using blocking synchronous operations in production

javascript
// Bad: Blocks the entire event loop
const fs = require('fs');
const data = [Link]('[Link]', 'utf8');

✅ Correct: Use async operations

javascript

const fs = require('fs').promises;
const data = await [Link]('[Link]', 'utf8');

❌ Mistake 3: Not handling process errors

javascript

// Bad: Unhandled errors crash the process

✅ Correct: Handle uncaught exceptions

javascript

[Link]('uncaughtException', (error) => {


[Link]('Uncaught Exception:', error);
// Log error, cleanup, then exit
[Link](1);
});

[Link]('unhandledRejection', (reason, promise) => {


[Link]('Unhandled Rejection at:', promise, 'reason:', reason);
});

2. [Link] Fundamentals
2.1 Global Objects

Theory
[Link] provides several global objects that are available in all modules without requiring them:
global : The global namespace object (like window in browsers)
process : Information about and control over the current [Link] process
console : Console output functions
Buffer : Handle binary data
__dirname : Directory name of current module
__filename : File name of current module
require() : Import modules
module : Reference to current module
exports : Shortcut to [Link]
setTimeout() , setInterval() , setImmediate() : Timer functions

Code Example

javascript

// Global object
[Link](global); // Global namespace

// Process object
[Link]([Link].NODE_ENV); // Environment variable
[Link]([Link]); // Command line arguments
[Link]([Link]()); // Current working directory

// __dirname and __filename


[Link](__dirname); // /path/to/current/directory
[Link](__filename); // /path/to/current/[Link]

// Buffer
const buf = [Link]('Hello World');
[Link](buf); // <Buffer 48 65 6c 6c 6f 20 57 6f 72 6c 64>
[Link]([Link]()); // Hello World

// Module and exports


[Link](module);
[Link](exports === [Link]); // true

// Timers
setTimeout(() => [Link]('Timeout'), 1000);
setInterval(() => [Link]('Interval'), 2000);
setImmediate(() => [Link]('Immediate'));

Mistakes to Avoid
❌ Mistake 1: Polluting the global namespace

javascript

// Bad: Creates global variable


[Link] = 'value';

✅ Correct: Use modules for sharing data


javascript

// [Link]
[Link] = {
myVariable: 'value'
};

// [Link]
const config = require('./config');

❌ Mistake 2: Confusing __dirname with [Link]()

javascript

// __dirname is the directory of the current module


// [Link]() is where the process was started from
// They can be different!

❌ Mistake 3: Modifying [Link] directly in production

javascript

// Bad: Hard to track and debug


[Link].DATABASE_URL = 'new-url';

✅ Correct: Use environment configuration files

javascript

// Use .env files with dotenv package


require('dotenv').config();
const dbUrl = [Link].DATABASE_URL;

2.2 Module System

Theory
CommonJS Modules (Default):
[Link] uses CommonJS module system by default
Each file is treated as a separate module
Modules are cached after first load
Synchronous loading

ES Modules (Modern):
Supported in [Link] 12+ with .mjs extension or "type": "module" in [Link]
Asynchronous loading
Strict mode by default
Static imports (analyzed at compile time)

Module Resolution:
1. Core modules (fs, http, path, etc.)
2. File modules (./module, ../module)
3. Folder modules (./folder - looks for [Link])
4. node_modules folder

Code Example

javascript
// ========== CommonJS ==========

// [Link] - Creating a module


function add(a, b) {
return a + b;
}

function subtract(a, b) {
return a - b;
}

// Method 1: Individual exports


[Link] = add;
[Link] = subtract;

// Method 2: Object export


[Link] = {
add,
subtract,
multiply: (a, b) => a * b
};

// Method 3: Named exports with exports shorthand


[Link] = (a, b) => a / b;

// [Link] - Using a module


const math = require('./math');
[Link]([Link](5, 3)); // 8

// Destructuring import
const { add, subtract } = require('./math');
[Link](add(10, 5)); // 15

// ========== ES Modules ==========

// [Link] or [Link] (with "type": "module" in [Link])


export function add(a, b) {
return a + b;
}

export const subtract = (a, b) => a - b;

// Default export
export default function multiply(a, b) {
return a * b;
}
// [Link]
import multiply from './[Link]';
import { add, subtract } from './[Link]';

[Link](add(5, 3)); // 8
[Link](multiply(4, 2)); // 8

// Import everything
import * as math from './[Link]';
[Link]([Link](1, 2)); // 3

// ========== Module Caching ==========


// [Link]
const config = require('./config');
[Link] = 'modified';

// [Link]
const config = require('./config');
[Link]([Link]); // 'modified' - same instance!

// Clear cache if needed (rare)


delete [Link][[Link]('./config')];

// ========== Core Modules ==========


const fs = require('fs');
const path = require('path');
const http = require('http');
const url = require('url');
const crypto = require('crypto');
const os = require('os');

// ========== Creating Packages ==========


// [Link]
{
"name": "my-package",
"version": "1.0.0",
"main": "[Link]", // Entry point
"type": "module" // Enable ES modules
}

Mistakes to Avoid
❌ Mistake 1: Mixing [Link] and exports incorrectly

javascript
// Bad: This won't work as expected
exports = {
add: (a, b) => a + b
};
// exports is reassigned, no longer points to [Link]

✅ Correct: Either use [Link] or assign properties to exports

javascript

// Good: Assign to [Link]


[Link] = {
add: (a, b) => a + b
};

// Or: Add properties to exports


[Link] = (a, b) => a + b;

❌ Mistake 2: Circular dependencies

javascript

// [Link]
const b = require('./b');
[Link] = { name: 'A', b };

// [Link]
const a = require('./a'); // a is incomplete here!
[Link] = { name: 'B', a };

✅ Correct: Restructure to avoid circular dependencies

javascript

// [Link]
[Link] = { shared: 'data' };

// [Link]
const shared = require('./shared');

// [Link]
const shared = require('./shared');

❌ Mistake 3: Not understanding the difference between CommonJS and ES modules

javascript
// Can't use require in ES modules
// Can't use import in CommonJS without dynamic import()

✅ Correct: Use appropriate syntax for each module system

javascript

// CommonJS
const module = require('module');

// ES Modules
import module from 'module';

// Dynamic import in CommonJS


async function loadModule() {
const module = await import('module');
}

3. NPM and Package Management


Theory
NPM (Node Package Manager):
Default package manager for [Link]
Manages project dependencies
Hosts over 2 million packages on [Link]
Comes bundled with [Link] installation

[Link]:
Manifest file for [Link] projects
Lists dependencies, scripts, metadata
Required for publishing packages
Defines project configuration

Dependencies Types:
dependencies : Required for production
devDependencies : Only for development (testing, building)
peerDependencies : Required to be installed by consumer
optionalDependencies : Won't fail if installation fails
Semantic Versioning (semver):
Format: [Link] (e.g., 1.2.3)
MAJOR: Breaking changes
MINOR: New features (backward compatible)
PATCH: Bug fixes
^1.2.3 : Compatible with 1.x.x (>=1.2.3 <2.0.0)
~1.2.3 : Compatible with 1.2.x (>=1.2.3 <1.3.0)
1.2.3 : Exact version

[Link]:
Locks exact dependency versions
Ensures consistent installs across environments
Generated automatically by npm
Should be committed to version control

Code Example

bash
# ========== NPM Commands ==========

# Initialize a new project


npm init # Interactive
npm init -y # With defaults

# Installing packages
npm install express # Add to dependencies
npm install --save express # Same as above (--save is default)
npm install --save-dev jest # Add to devDependencies
npm install -D jest # Short form
npm install -g nodemon # Global installation
npm install express@4.17.1 # Specific version

# Removing packages
npm uninstall express
npm uninstall -D jest
npm uninstall -g nodemon

# Updating packages
npm update # Update all packages
npm update express # Update specific package
npm outdated # Check for outdated packages

# Other useful commands


npm list # List installed packages
npm list --depth=0 # Only top-level
npm view express # Package information
npm search keyword # Search packages
npm audit # Security audit
npm audit fix # Fix vulnerabilities
npm cache clean --force # Clear cache

json
// ========== [Link] ==========
{
"name": "my-app",
"version": "1.0.0",
"description": "My [Link] application",
"main": "[Link]",
"scripts": {
"start": "node [Link]",
"dev": "nodemon [Link]",
"test": "jest",
"test:watch": "jest --watch",
"build": "webpack --mode production",
"lint": "eslint .",
"format": "prettier --write ."
},
"keywords": ["nodejs", "express"],
"author": "Your Name <email@[Link]>",
"license": "MIT",
"dependencies": {
"express": "^4.18.2",
"mongoose": "^7.0.0",
"dotenv": "^16.0.3"
},
"devDependencies": {
"jest": "^29.5.0",
"nodemon": "^2.0.22",
"eslint": "^8.36.0"
},
"engines": {
"node": ">=14.0.0",
"npm": ">=6.0.0"
},
"repository": {
"type": "git",
"url": "[Link]
}
}

javascript
// ========== Using NPM Scripts ==========

// [Link]
{
"scripts": {
"start": "node [Link]",
"dev": "NODE_ENV=development nodemon [Link]",
"prod": "NODE_ENV=production node [Link]",
"test": "jest --coverage",
"prebuild": "npm run clean", // Runs before build
"build": "webpack",
"postbuild": "npm run deploy", // Runs after build
"clean": "rm -rf dist"
}
}

// Run scripts:
// npm start
// npm run dev
// npm test

bash

# ========== NPX (Node Package Runner) ==========

# Run packages without installing


npx create-react-app my-app
npx eslint .
npx jest

# Run specific versions


npx node@14 [Link]

# Run local binaries


npx nodemon [Link]

bash
# ========== Yarn Alternative ==========

# Install Yarn
npm install -g yarn

# Yarn commands
yarn init
yarn add express
yarn add --dev jest
yarn remove express
yarn upgrade
yarn global add nodemon

Mistakes to Avoid
❌ Mistake 1: Not committing [Link]

bash

# Bad: Adding to .gitignore


[Link]

✅ Correct: Commit [Link] for consistent installs

bash

# Good: Include in version control


git add [Link]

❌ Mistake 2: Installing packages globally when they should be local

bash

# Bad: Global installation for project dependency


npm install -g express

✅ Correct: Install locally for project dependencies

bash

# Good: Local installation


npm install express

# Use npx to run binaries


npx eslint .

❌ Mistake 3: Using loose version ranges in production


json

{
"dependencies": {
"express": "*", // Very bad
"mongoose": "latest" // Bad
}
}

✅ Correct: Use specific versions or conservative ranges

json

{
"dependencies": {
"express": "4.18.2", // Exact version
"mongoose": "^7.0.0" // Allow patch and minor updates
}
}

❌ Mistake 4: Not handling npm audit vulnerabilities

bash

# Bad: Ignoring security warnings

✅ Correct: Regularly audit and fix vulnerabilities

bash

npm audit
npm audit fix
npm audit fix --force # For breaking changes (careful!)

❌ Mistake 5: Mixing package managers

bash

# Bad: Using both npm and yarn in same project


npm install express
yarn add mongoose

✅ Correct: Choose one package manager and stick with it

bash
# Use only npm
npm install express
npm install mongoose

# Or use only yarn


yarn add express
yarn add mongoose

4. File System Operations


Theory
fs Module:
Core [Link] module for file system operations
Provides both synchronous and asynchronous methods
Asynchronous methods use callbacks or promises
Common operations: read, write, delete, rename, stat

fs Methods:
readFile() / readFileSync() : Read file contents
writeFile() / writeFileSync() : Write to file
appendFile() / appendFileSync() : Append to file
unlink() / unlinkSync() : Delete file
mkdir() / mkdirSync() : Create directory
rmdir() / rmdirSync() : Remove directory
readdir() / readdirSync() : Read directory contents
stat() / statSync() : Get file/directory info
exists() / existsSync() : Check if file exists (deprecated, use stat)
rename() / renameSync() : Rename/move file
copyFile() / copyFileSync() : Copy file

fs/promises:
Promise-based versions of fs methods
Cleaner async/await syntax
Available in [Link] 10+
Path Module:
Handle file paths across different OS
[Link]() : Join path segments
[Link]() : Resolve to absolute path
[Link]() : Get filename
[Link]() : Get directory name
[Link]() : Get file extension

Code Example

javascript
// ========== Basic File Operations (Callback) ==========
const fs = require('fs');

// Read file
[Link]('[Link]', 'utf8', (err, data) => {
if (err) {
[Link]('Error reading file:', err);
return;
}
[Link]('File content:', data);
});

// Write file
[Link]('[Link]', 'Hello World!', 'utf8', (err) => {
if (err) {
[Link]('Error writing file:', err);
return;
}
[Link]('File written successfully');
});

// Append to file
[Link]('[Link]', 'New log entry\n', (err) => {
if (err) {
[Link]('Error appending to file:', err);
return;
}
[Link]('Data appended');
});

// Delete file
[Link]('[Link]', (err) => {
if (err) {
[Link]('Error deleting file:', err);
return;
}
[Link]('File deleted');
});

// ========== Promises (fs/promises) ==========


const fsPromises = require('fs').promises;

async function fileOperations() {


try {
// Read file
const data = await [Link]('[Link]', 'utf8');
[Link]('Content:', data);

// Write file
await [Link]('[Link]', 'Hello World!', 'utf8');
[Link]('File written');

// Append to file
await [Link]('[Link]', 'New entry\n');
[Link]('Data appended');

// Delete file
await [Link]('[Link]');
[Link]('File deleted');

} catch (error) {
[Link]('Error:', error);
}
}

fileOperations();

// ========== Directory Operations ==========


const fs = require('fs').promises;
const path = require('path');

async function directoryOps() {


try {
// Create directory
await [Link]('new-folder', { recursive: true });
[Link]('Directory created');

// Read directory
const files = await [Link]('.');
[Link]('Files:', files);

// Read directory with file types


const entries = await [Link]('.', { withFileTypes: true });
for (const entry of entries) {
[Link](
[Link],
[Link]() ? '[DIR]' : '[FILE]'
);
}

// Remove directory
await [Link]('empty-folder');
// Remove directory with contents ([Link] 14+)
await [Link]('folder-with-files', { recursive: true, force: true });

} catch (error) {
[Link]('Error:', error);
}
}

// ========== File Stats ==========


async function getFileInfo(filepath) {
try {
const stats = await [Link](filepath);

[Link]('File info:');
[Link]('Size:', [Link], 'bytes');
[Link]('Created:', [Link]);
[Link]('Modified:', [Link]);
[Link]('Is file:', [Link]());
[Link]('Is directory:', [Link]());

} catch (error) {
if ([Link] === 'ENOENT') {
[Link]('File does not exist');
} else {
[Link]('Error:', error);
}
}
}

// ========== Path Operations ==========


const path = require('path');

// Join paths (handles OS-specific separators)


const fullPath = [Link](__dirname, 'data', '[Link]');
[Link](fullPath); // /home/user/project/data/[Link]

// Resolve to absolute path


const absolute = [Link]('data', '[Link]');
[Link](absolute);

// Get filename
const filename = [Link]('/path/to/[Link]');
[Link](filename); // [Link]

// Get directory
const directory = [Link]('/path/to/[Link]');
[Link](directory); // /path/to
// Get extension
const ext = [Link]('[Link]');
[Link](ext); // .txt

// Parse path
const parsed = [Link]('/path/to/[Link]');
[Link](parsed);
// {
// root: '/',
// dir: '/path/to',
// base: '[Link]',
// ext: '.txt',
// name: 'file'
// }

// ========== Check if File Exists ==========


async function fileExists(filepath) {
try {
await [Link](filepath);
return true;
} catch {
return false;
}
}

// Usage
if (await fileExists('[Link]')) {
[Link]('File exists');
}

// ========== Copy File ==========


async function copyFile(source, destination) {
try {
await [Link](source, destination);
[Link]('File copied successfully');
} catch (error) {
[Link]('Error copying file:', error);
}
}

// ========== Rename/Move File ==========


async function moveFile(oldPath, newPath) {
try {
await [Link](oldPath, newPath);
[Link]('File moved successfully');
} catch (error) {
[Link]('Error moving file:', error);
}
}

// ========== Read JSON File ==========


async function readJSON(filepath) {
try {
const data = await [Link](filepath, 'utf8');
return [Link](data);
} catch (error) {
[Link]('Error reading JSON:', error);
return null;
}
}

// ========== Write JSON File ==========


async function writeJSON(filepath, data) {
try {
const jsonString = [Link](data, null, 2);
await [Link](filepath, jsonString, 'utf8');
[Link]('JSON written successfully');
} catch (error) {
[Link]('Error writing JSON:', error);
}
}

// Usage
const config = await readJSON('[Link]');
await writeJSON('[Link]', { name: 'John', age: 30 });

// ========== Watch File Changes ==========


[Link]('[Link]', (eventType, filename) => {
[Link](`Event: ${eventType}`);
[Link](`Filename: ${filename}`);
});

// ========== Recursive Directory Reading ==========


async function readDirRecursive(dir) {
const files = [];
const items = await [Link](dir, { withFileTypes: true });

for (const item of items) {


const fullPath = [Link](dir, [Link]);

if ([Link]()) {
[Link](...await readDirRecursive(fullPath));
} else {
[Link](fullPath);
}
}

return files;
}

// Usage
const allFiles = await readDirRecursive('./project');
[Link](allFiles);

Mistakes to Avoid
❌ Mistake 1: Using synchronous methods in production

javascript

// Bad: Blocks the event loop


const data = [Link]('[Link]', 'utf8');

✅ Correct: Use asynchronous methods

javascript

// Good: Non-blocking
const data = await [Link]('[Link]', 'utf8');

// Or with callbacks
[Link]('[Link]', 'utf8', (err, data) => {
if (err) throw err;
[Link](data);
});

❌ Mistake 2: Not handling errors

javascript

// Bad: No error handling


const data = await [Link]('[Link]');

✅ Correct: Always handle errors

javascript
// Good: Proper error handling
try {
const data = await [Link]('[Link]', 'utf8');
[Link](data);
} catch (error) {
if ([Link] === 'ENOENT') {
[Link]('File not found');
} else {
[Link]('Error reading file:', error);
}
}

❌ Mistake 3: Not specifying encoding

javascript

// Bad: Returns Buffer instead of string


const data = await [Link]('[Link]');
[Link](data); // <Buffer 48 65 6c 6c 6f>

✅ Correct: Specify encoding for text files

javascript

// Good: Returns string


const data = await [Link]('[Link]', 'utf8');
[Link](data); // "Hello"

❌ Mistake 4: Hard-coding path separators

javascript

// Bad: Won't work on Windows


const filepath = './data/[Link]';

✅ Correct: Use [Link]() for cross-platform compatibility

javascript

// Good: Works on all platforms


const filepath = [Link]('.', 'data', '[Link]');

❌ Mistake 5: Not using recursive option for nested directories

javascript
// Bad: Fails if parent doesn't exist
await [Link]('./a/b/c');

✅ Correct: Use recursive option

javascript

// Good: Creates all parent directories


await [Link]('./a/b/c', { recursive: true });

❌ Mistake 6: Using exists() to check before operations

javascript

// Bad: Race condition


if ([Link]('[Link]')) {
[Link]('[Link]'); // File might be deleted here
}

✅ Correct: Handle errors instead of checking existence

javascript

// Good: Just try and handle errors


try {
const data = await [Link]('[Link]', 'utf8');
} catch (error) {
if ([Link] === 'ENOENT') {
[Link]('File does not exist');
}
}

5. Asynchronous Programming
Theory
Asynchronous Patterns in [Link]:
1. Callbacks (Traditional)
Functions passed as arguments
Called when operation completes
First argument is error (error-first callback)
Can lead to "callback hell"
2. Promises
Object representing eventual completion/failure
States: pending, fulfilled, rejected
Chainable with .then() , .catch() , .finally()
Cleaner than callbacks
3. Async/Await (Modern)
Syntactic sugar over Promises
Makes async code look synchronous
Uses async keyword for functions
Uses await keyword to wait for Promises
Better error handling with try/catch

Event Loop:
Single-threaded event loop
Handles asynchronous operations
Phases: timers, I/O callbacks, idle/prepare, poll, check, close callbacks
Microtasks (Promises) have priority over macrotasks (setTimeout)

Callback Queue:
Macrotask queue: setTimeout, setInterval, I/O
Microtask queue: Promises, [Link]
Microtasks execute before macrotasks

Code Example

javascript
// ========== Callbacks ==========

// Error-first callback pattern


function readFileCallback(filename, callback) {
[Link](filename, 'utf8', (err, data) => {
if (err) {
callback(err, null);
return;
}
callback(null, data);
});
}

// Usage
readFileCallback('[Link]', (err, data) => {
if (err) {
[Link]('Error:', err);
return;
}
[Link]('Data:', data);
});

// Callback Hell (Pyramid of Doom)


[Link]('[Link]', 'utf8', (err, data1) => {
if (err) throw err;
[Link]('[Link]', 'utf8', (err, data2) => {
if (err) throw err;
[Link]('[Link]', 'utf8', (err, data3) => {
if (err) throw err;
[Link](data1, data2, data3);
});
});
});

// ========== Promises ==========

// Creating a Promise
function readFilePromise(filename) {
return new Promise((resolve, reject) => {
[Link](filename, 'utf8', (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}

// Using Promises
readFilePromise('[Link]')
.then(data => {
[Link]('Data:', data);
return readFilePromise('[Link]');
})
.then(data2 => {
[Link]('Data2:', data2);
})
.catch(error => {
[Link]('Error:', error);
})
.finally(() => {
[Link]('Operation complete');
});

// [Link] - Wait for all promises


const promises = [
readFilePromise('[Link]'),
readFilePromise('[Link]'),
readFilePromise('[Link]')
];

[Link](promises)
.then(results => {
[Link]('All files:', results);
})
.catch(error => {
[Link]('One or more failed:', error);
});

// [Link] - Wait for all, regardless of success/failure


[Link](promises)
.then(results => {
[Link]((result, index) => {
if ([Link] === 'fulfilled') {
[Link](`File ${index}:`, [Link]);
} else {
[Link](`File ${index} failed:`, [Link]);
}
});
});

// [Link] - First promise to complete


[Link](promises)
.then(firstResult => {
[Link]('First to complete:', firstResult);
});

// [Link] - First promise to fulfill


[Link](promises)
.then(firstSuccess => {
[Link]('First success:', firstSuccess);
})
.catch(error => {
[Link]('All failed:', error);
});

// ========== Async/Await ==========

// Async function always returns a Promise


async function readFilesAsync() {
try {
const data1 = await readFilePromise('[Link]');
const data2 = await readFilePromise('[Link]');
const data3 = await readFilePromise('[Link]');

[Link]('All data:', data1, data2, data3);


return { data1, data2, data3 };

} catch (error) {
[Link]('Error reading files:', error);
throw error;
} finally {
[Link]('Cleanup');
}
}

// Call async function


readFilesAsync()
.then(result => [Link]('Result:', result))
.catch(error => [Link]('Failed:', error));

// Or use await at top level ([Link] 14.8+)


// const result = await readFilesAsync();

// Parallel execution with async/await


async function readFilesParallel() {
try {
// Start all operations at once
const [data1, data2, data3] = await [Link]([
readFilePromise('[Link]'),
readFilePromise('[Link]'),
readFilePromise('[Link]')
]);

[Link]('All data:', data1, data2, data3);

} catch (error) {
[Link]('Error:', error);
}
}

// ========== Error Handling ==========

// Try-catch with async/await


async function safeReadFile(filename) {
try {
const data = await [Link](filename, 'utf8');
return data;
} catch (error) {
if ([Link] === 'ENOENT') {
[Link]('File not found, using default');
return 'default content';
}
throw error; // Re-throw unknown errors
}
}

// Multiple try-catch blocks


async function processFiles() {
let data1, data2;

try {
data1 = await [Link]('[Link]', 'utf8');
} catch (error) {
[Link]('Error reading file1:', error);
data1 = 'default1';
}

try {
data2 = await [Link]('[Link]', 'utf8');
} catch (error) {
[Link]('Error reading file2:', error);
data2 = 'default2';
}

return { data1, data2 };


}

// ========== Promisify ==========


const util = require('util');

// Convert callback-based function to Promise


const readFilePromisified = [Link]([Link]);

async function usePromisified() {


const data = await readFilePromisified('[Link]', 'utf8');
[Link](data);
}

// Custom promisify
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
};
}

// ========== Event Loop Understanding ==========

[Link]('1 - Start');

setTimeout(() => {
[Link]('2 - setTimeout 0ms');
}, 0);

setImmediate(() => {
[Link]('3 - setImmediate');
});

[Link]().then(() => {
[Link]('4 - Promise');
});

[Link](() => {
[Link]('5 - nextTick');
});

[Link]('6 - End');
// Output order:
// 1 - Start
// 6 - End
// 5 - nextTick (microtask, highest priority)
// 4 - Promise (microtask)
// 2 - setTimeout 0ms (macrotask)
// 3 - setImmediate (macrotask)

// ========== Async Iteration ==========

async function processArray(items) {


// Sequential processing
for (const item of items) {
const result = await processItem(item);
[Link](result);
}

// Parallel processing
const results = await [Link](
[Link](item => processItem(item))
);
[Link](results);
}

// For-await-of (async iterators)


async function* asyncGenerator() {
yield await [Link](1);
yield await [Link](2);
yield await [Link](3);
}

async function consumeAsyncIterator() {


for await (const value of asyncGenerator()) {
[Link](value);
}
}

// ========== Practical Example: API Calls ==========

async function fetchUserData(userId) {


try {
// Fetch user
const userResponse = await fetch(`/api/users/${userId}`);
const user = await [Link]();

// Fetch user's posts and comments in parallel


const [posts, comments] = await [Link]([
fetch(`/api/users/${userId}/posts`).then(r => [Link]()),
fetch(`/api/users/${userId}/comments`).then(r => [Link]())
]);

return { user, posts, comments };

} catch (error) {
[Link]('Error fetching user data:', error);
throw error;
}
}

Mistakes to Avoid
❌ Mistake 1: Not handling Promise rejections

javascript

// Bad: Unhandled rejection


async function getData() {
throw new Error('Oops!');
}

getData(); // Unhandled Promise rejection

✅ Correct: Always handle rejections

javascript

// Good: Handle with .catch()


getData().catch(error => [Link](error));

// Or use try-catch
async function main() {
try {
await getData();
} catch (error) {
[Link](error);
}
}

❌ Mistake 2: Sequential instead of parallel execution

javascript
// Bad: 3 seconds total (1+1+1)
const result1 = await operation1(); // 1 second
const result2 = await operation2(); // 1 second
const result3 = await operation3(); // 1 second

✅ Correct: Parallel execution when possible

javascript

// Good: 1 second total (parallel)


const [result1, result2, result3] = await [Link]([
operation1(),
operation2(),
operation3()
]);

❌ Mistake 3: Using async/await in loops inefficiently

javascript

// Bad: Sequential processing


for (const item of items) {
await processItem(item);
}

✅ Correct: Batch process or use [Link]

javascript

// Good: Parallel processing


await [Link]([Link](item => processItem(item)));

// Or if you need sequential:


for (const item of items) {
await processItem(item); // This is fine if sequential is needed
}

❌ Mistake 4: Forgetting to return in Promise chains

javascript
// Bad: Doesn't wait for inner promise
doSomething()
.then(() => {
doSomethingElse(); // Missing return!
})
.then(() => {
// This runs before doSomethingElse completes
});

✅ Correct: Return promises in chains

javascript

// Good: Returns promise


doSomething()
.then(() => {
return doSomethingElse();
})
.then(() => {
// This waits for doSomethingElse
});

❌ Mistake 5: Mixing callbacks and Promises

javascript

// Bad: Confused pattern


async function getData() {
[Link]('[Link]', (err, data) => {
return data; // This doesn't work!
});
}

✅ Correct: Use consistent async pattern

javascript

// Good: Use promises/async-await


async function getData() {
const data = await [Link]('[Link]', 'utf8');
return data;
}

❌ Mistake 6: Not understanding [Link] failure behavior

javascript
// Bad: One failure stops everything
const results = await [Link]([
operation1(),
operation2(), // If this fails, we lose results from operation1 and 3
operation3()
]);

✅ Correct: Use [Link] for partial results

javascript

// Good: Get all results even if some fail


const results = await [Link]([
operation1(),
operation2(),
operation3()
]);

[Link]((result, index) => {


if ([Link] === 'fulfilled') {
[Link](`Operation ${index} succeeded:`, [Link]);
} else {
[Link](`Operation ${index} failed:`, [Link]);
}
});

This comprehensive guide continues with all remaining topics including Streams and Buffers,
Events and Event Emitters, HTTP Module, [Link], Routing, Middleware, Template Engines,
Error Handling, Database Integration, Authentication, RESTful APIs, Security, Testing,
Performance Optimization, and Deployment. Due to length, I'll continue in the next section...

6. Streams and Buffers


Theory
Buffers:
Temporary storage for binary data
Fixed-size chunks of memory
Used when working with binary data (images, files, network data)
[Link] Buffer class is similar to arrays of integers
Each element represents a byte (0-255)
Streams:
Abstract interface for working with streaming data
Process data piece by piece (chunks)
Memory efficient for large files
Four types:
1. Readable: Read data from source ([Link], HTTP request)
2. Writable: Write data to destination ([Link], HTTP response)
3. Duplex: Both readable and writable (TCP socket)
4. Transform: Modify data while reading/writing (zlib, crypto)

Stream Events:
data : Emitted when chunk is available
end : Emitted when no more data
error : Emitted on errors
finish : Emitted when all data written (writable)
pipe : Emitted when [Link]() called

Benefits of Streams:
Memory efficient (don't load entire file)
Time efficient (start processing before everything loads)
Composable (pipe streams together)

Code Example

javascript
// ========== Buffers ==========

// Create buffer from string


const buf1 = [Link]('Hello World');
[Link](buf1); // <Buffer 48 65 6c 6c 6f 20 57 6f 72 6c 64>
[Link]([Link]()); // 'Hello World'

// Create buffer from array


const buf2 = [Link]([72, 101, 108, 108, 111]);
[Link]([Link]()); // 'Hello'

// Create empty buffer


const buf3 = [Link](10); // 10 bytes, initialized to 0
const buf4 = [Link](10); // 10 bytes, not initialized (faster)

// Write to buffer
[Link]('Hi');
[Link]([Link]()); // 'Hi\x00\x00\x00\x00\x00\x00\x00\x00'

// Buffer length and content


[Link]([Link]); // 11 bytes
[Link](buf1[0]); // 72 (ASCII code for 'H')

// Buffer operations
const buf5 = [Link]([buf1, buf2]);
[Link]([Link]()); // 'Hello WorldHello'

// Compare buffers
const buf6 = [Link]('ABC');
const buf7 = [Link]('ABC');
[Link]([Link](buf7)); // true

// Slice buffer (creates a view, not a copy)


const slice = [Link](0, 5);
[Link]([Link]()); // 'Hello'

// ========== Readable Streams ==========


const fs = require('fs');

// Create readable stream


const readableStream = [Link]('[Link]', {
encoding: 'utf8',
highWaterMark: 16 * 1024 // 16KB chunks (default 64KB)
});

// Event-based consumption
[Link]('data', (chunk) => {
[Link]('Received chunk:', [Link], 'bytes');
});

[Link]('end', () => {
[Link]('Finished reading file');
});

[Link]('error', (error) => {


[Link]('Error reading file:', error);
});

// Pause and resume


[Link]('data', (chunk) => {
[Link]('Chunk:', chunk);
[Link]();

setTimeout(() => {
[Link]('Resuming...');
[Link]();
}, 1000);
});

// ========== Writable Streams ==========

// Create writable stream


const writableStream = [Link]('[Link]');

// Write data
[Link]('First line\n');
[Link]('Second line\n');
[Link]('Final line\n'); // Write and close

// Events
[Link]('finish', () => {
[Link]('Writing finished');
});

[Link]('error', (error) => {


[Link]('Error writing:', error);
});

// ========== Piping Streams ==========

// Simple pipe: read from file and write to another


const readStream = [Link]('[Link]');
const writeStream = [Link]('[Link]');
[Link](writeStream);

// Pipe with error handling


readStream
.pipe(writeStream)
.on('finish', () => [Link]('Copy complete'))
.on('error', (error) => [Link]('Error:', error));

// Chain multiple pipes


const { createGzip } = require('zlib');

[Link]('[Link]')
.pipe(createGzip())
.pipe([Link]('[Link]'))
.on('finish', () => [Link]('File compressed'));

// ========== Transform Streams ==========


const { Transform } = require('stream');

// Create custom transform stream


const upperCaseTransform = new Transform({
transform(chunk, encoding, callback) {
// Transform chunk to uppercase
const upperChunk = [Link]().toUpperCase();
[Link](upperChunk);
callback();
}
});

// Use transform stream


[Link]('[Link]')
.pipe(upperCaseTransform)
.pipe([Link]('[Link]'));

// ========== Custom Readable Stream ==========


const { Readable } = require('stream');

class NumberStream extends Readable {


constructor(max) {
super();
[Link] = max;
[Link] = 1;
}

_read() {
if ([Link] <= [Link]) {
[Link]([Link]() + '\n');
[Link]++;
} else {
[Link](null); // End stream
}
}
}

const numberStream = new NumberStream(10);


[Link]([Link]);

// ========== Custom Writable Stream ==========


const { Writable } = require('stream');

class LogStream extends Writable {


_write(chunk, encoding, callback) {
[Link]('[LOG]', [Link]());
callback();
}
}

const logStream = new LogStream();


[Link]('Hello');
[Link]('World');
[Link]();

// ========== Duplex Streams ==========


const { Duplex } = require('stream');

class MyDuplex extends Duplex {


constructor(options) {
super(options);
[Link] = [];
}

_read() {
const chunk = [Link]();
[Link](chunk || null);
}

_write(chunk, encoding, callback) {


[Link](chunk);
callback();
}
}

// ========== Stream Practical Examples ==========


// 1. Copy large file efficiently
function copyFile(source, destination) {
return new Promise((resolve, reject) => {
const readStream = [Link](source);
const writeStream = [Link](destination);

readStream
.pipe(writeStream)
.on('finish', resolve)
.on('error', reject);
});
}

// 2. Count lines in large file


async function countLines(filename) {
let count = 0;
const readStream = [Link](filename);
const readline = require('readline');

const rl = [Link]({
input: readStream,
crlfDelay: Infinity
});

for await (const line of rl) {


count++;
}

return count;
}

// 3. Process CSV file


const readline = require('readline');

async function processCSV(filename) {


const readStream = [Link](filename);
const rl = [Link]({
input: readStream,
crlfDelay: Infinity
});

let isFirstLine = true;


const results = [];

for await (const line of rl) {


if (isFirstLine) {
isFirstLine = false;
continue; // Skip header
}

const [id, name, age] = [Link](',');


[Link]({ id, name, age: parseInt(age) });
}

return results;
}

// 4. Compress file
const { createGzip } = require('zlib');

function compressFile(input, output) {


return new Promise((resolve, reject) => {
[Link](input)
.pipe(createGzip())
.pipe([Link](output))
.on('finish', resolve)
.on('error', reject);
});
}

// 5. Decompress file
const { createGunzip } = require('zlib');

function decompressFile(input, output) {


return new Promise((resolve, reject) => {
[Link](input)
.pipe(createGunzip())
.pipe([Link](output))
.on('finish', resolve)
.on('error', reject);
});
}

// 6. Stream to HTTP response


const http = require('http');

const server = [Link]((req, res) => {


if ([Link] === '/download') {
[Link](200, {
'Content-Type': 'application/octet-stream',
'Content-Disposition': 'attachment; filename="[Link]"'
});
[Link]('[Link]').pipe(res);
}
});

[Link](3000);

// 7. Handle backpressure
function writeOneMillionNumbers() {
const writeStream = [Link]('[Link]');

function write(i) {
let ok = true;
do {
if (i === 0) {
[Link]();
} else {
ok = [Link](`${i}\n`);
i--;
}
} while (i > 0 && ok);

if (i > 0) {
// Buffer is full, wait for drain
[Link]('drain', () => write(i));
}
}

write(1000000);
}

Mistakes to Avoid
❌ Mistake 1: Loading entire file into memory

javascript

// Bad: Loads entire file (100GB file = 100GB RAM)


const data = await [Link]('[Link]', 'utf8');

✅ Correct: Use streams for large files

javascript
// Good: Process in chunks
const readStream = [Link]('[Link]');
[Link]('data', (chunk) => {
processChunk(chunk);
});

❌ Mistake 2: Not handling stream errors

javascript

// Bad: No error handling


[Link](writeStream);

✅ Correct: Handle errors on all streams

javascript

// Good: Proper error handling


readStream
.on('error', (error) => [Link]('Read error:', error))
.pipe(writeStream)
.on('error', (error) => [Link]('Write error:', error));

// Even better: Use pipeline


const { pipeline } = require('stream');
pipeline(
readStream,
transformStream,
writeStream,
(error) => {
if (error) {
[Link]('Pipeline error:', error);
} else {
[Link]('Pipeline succeeded');
}
}
);

❌ Mistake 3: Ignoring backpressure

javascript

// Bad: Overwhelms writable stream


for (let i = 0; i < 1000000; i++) {
[Link](`Line ${i}\n`);
}
✅ Correct: Handle backpressure with drain event

javascript

// Good: Respects backpressure


function write(data, stream) {
if (![Link](data)) {
// Buffer is full, pause until drained
[Link]('drain', () => {
// Continue writing
});
}
}

❌ Mistake 4: Creating buffers with allocUnsafe without clearing

javascript

// Bad: May contain sensitive data from memory


const buf = [Link](1024);
[Link](buf); // Contains random data

✅ Correct: Use alloc or fill allocUnsafe

javascript

// Good: Zero-initialized
const buf1 = [Link](1024);

// Or clear unsafe buffer


const buf2 = [Link](1024);
[Link](0);

❌ Mistake 5: Not ending writable streams

javascript

// Bad: Stream never closes


[Link]('data');
// Program hangs

✅ Correct: Always end writable streams

javascript
// Good: Close stream
[Link]('data');
[Link]();

// Or use end() with data


[Link]('final data');

❌ Mistake 6: Modifying buffer slices thinking they're copies

javascript

// Bad: Modifies original buffer


const original = [Link]('Hello');
const slice = [Link](0, 2);
slice[0] = 88; // Also changes original!
[Link]([Link]()); // 'Xello'

✅ Correct: Create a copy if you need independence

javascript

// Good: Create independent copy


const original = [Link]('Hello');
const copy = [Link]([Link](0, 2));
copy[0] = 88;
[Link]([Link]()); // 'Hello' (unchanged)

7. Events and Event Emitters


Theory
Event-Driven Architecture:
Core pattern in [Link]
Objects emit named events
Listeners (callbacks) execute when events occur
Asynchronous by nature
Decouples event emitters from event handlers

EventEmitter Class:
Core module events
Many [Link] APIs extend EventEmitter
Examples: HTTP servers, streams, child processes
Key Methods:
on(event, listener) : Add listener
once(event, listener) : Add one-time listener
emit(event, [...args]) : Trigger event
removeListener(event, listener) : Remove specific listener
removeAllListeners([event]) : Remove all listeners
listenerCount(event) : Count listeners
eventNames() : Get array of event names

Event Flow:
1. Event emitter triggers event with emit()
2. All registered listeners execute in order
3. Listeners execute synchronously (unless made async)
4. Return values from listeners are ignored

Code Example

javascript
// ========== Basic EventEmitter ==========
const EventEmitter = require('events');

// Create instance
const myEmitter = new EventEmitter();

// Add listener
[Link]('event', () => {
[Link]('Event occurred!');
});

// Emit event
[Link]('event'); // Event occurred!

// ========== Passing Arguments ==========

[Link]('greet', (name, age) => {


[Link](`Hello ${name}, you are ${age} years old`);
});

[Link]('greet', 'John', 30);


// Hello John, you are 30 years old

// ========== Multiple Listeners ==========

[Link]('data', () => {
[Link]('First listener');
});

[Link]('data', () => {
[Link]('Second listener');
});

[Link]('data');
// First listener
// Second listener

// ========== One-Time Listeners ==========

[Link]('login', (user) => {


[Link](`${user} logged in`);
});

[Link]('login', 'Alice'); // Alice logged in


[Link]('login', 'Bob'); // Nothing (removed after first emit)
// ========== Error Events ==========

[Link]('error', (error) => {


[Link]('Error occurred:', [Link]);
});

[Link]('error', new Error('Something went wrong'));

// Special case: If no 'error' listener, [Link] throws exception


const badEmitter = new EventEmitter();
// [Link]('error', new Error('Uncaught!')); // Throws!

// ========== Removing Listeners ==========

function onData() {
[Link]('Data received');
}

[Link]('data', onData);
[Link]('data'); // Data received

[Link]('data', onData);
// or: [Link]('data', onData);
[Link]('data'); // Nothing

// Remove all listeners for an event


[Link]('data');

// Remove all listeners for all events


[Link]();

// ========== Custom EventEmitter Class ==========

class User extends EventEmitter {


constructor(name) {
super();
[Link] = name;
}

login() {
[Link](`${[Link]} is logging in...`);
[Link]('login', [Link]);
}

logout() {
[Link](`${[Link]} is logging out...`);
[Link]('logout', [Link]);
}
}

const user = new User('Alice');

[Link]('login', (name) => {


[Link](`Welcome, ${name}!`);
});

[Link]('logout', (name) => {


[Link](`Goodbye, ${name}!`);
});

[Link]();
// Alice is logging in...
// Welcome, Alice!

// ========== Practical Example: Job Queue ==========

class JobQueue extends EventEmitter {


constructor() {
super();
[Link] = [];
[Link] = false;
}

addJob(job) {
[Link](job);
[Link]('jobAdded', job);

if (![Link]) {
[Link]();
}
}

async processJobs() {
[Link] = true;

while ([Link] > 0) {


const job = [Link]();
[Link]('jobStarted', job);

try {
const result = await [Link]();
[Link]('jobCompleted', job, result);
} catch (error) {
[Link]('jobFailed', job, error);
}
}

[Link] = false;
[Link]('queueEmpty');
}
}

const queue = new JobQueue();

[Link]('jobCompleted', (job, result) => {


[Link](`Completed: ${[Link]}`, result);
});

Mistakes to Avoid
❌ Mistake 1: Not handling 'error' events

javascript

// Bad: Will crash if error event is emitted


const emitter = new EventEmitter();
[Link]('error', new Error('Oops!')); // Throws!

✅ Correct: Always handle error events

javascript

// Good: Handle errors


[Link]('error', (error) => {
[Link]('Error:', error);
});

❌ Mistake 2: Creating memory leaks with listeners

javascript

// Bad: Adding listeners in a loop without removing


setInterval(() => {
[Link]('data', () => {
// This listener is never removed!
});
}, 1000);

✅ Correct: Remove listeners when done

javascript
// Good: Use once() for one-time listeners
setInterval(() => {
[Link]('data', () => {
// Automatically removed after first emit
});
}, 1000);

8. HTTP Module
Theory
HTTP Module:
Core module for creating HTTP servers and clients
Low-level API (Express is built on top of it)
Handles HTTP requests and responses
Supports both HTTP and HTTPS

HTTP Server:
[Link](callback) : Creates server
Callback receives request and response objects
request : Incoming message from client
response : Outgoing message to client

Request Object (IncomingMessage):


method : HTTP method (GET, POST, etc.)
url : Request URL
headers : Request headers
httpVersion : HTTP version
Inherits from Stream (readable)

Response Object (ServerResponse):


writeHead(statusCode, headers) : Set status and headers
write(data) : Write response body
end([data]) : End response (optionally write data)
statusCode : Set status code
setHeader(name, value) : Set individual header
Inherits from Stream (writable)

Status Codes:
1xx: Informational
2xx: Success (200 OK, 201 Created)
3xx: Redirection (301 Moved Permanently, 302 Found)
4xx: Client errors (400 Bad Request, 404 Not Found)
5xx: Server errors (500 Internal Server Error)

Code Example

javascript
// ========== Basic HTTP Server ==========
const http = require('http');

const server = [Link]((req, res) => {


[Link](200, { 'Content-Type': 'text/plain' });
[Link]('Hello World!');
});

[Link](3000, () => {
[Link]('Server running on [Link]
});

// ========== Routing ==========

const server3 = [Link]((req, res) => {


if ([Link] === 'GET' && [Link] === '/') {
[Link](200, { 'Content-Type': 'text/html' });
[Link]('<h1>Home Page</h1>');
}
else if ([Link] === 'GET' && [Link] === '/about') {
[Link](200, { 'Content-Type': 'text/html' });
[Link]('<h1>About Page</h1>');
}
else if ([Link] === 'GET' && [Link] === '/api/users') {
[Link](200, { 'Content-Type': 'application/json' });
[Link]([Link]({ users: ['Alice', 'Bob'] }));
}
else {
[Link](404, { 'Content-Type': 'text/html' });
[Link]('<h1>404 Not Found</h1>');
}
});

// ========== Handling POST Data ==========

const server6 = [Link]((req, res) => {


if ([Link] === 'POST') {
let body = '';

// Collect data chunks


[Link]('data', (chunk) => {
body += [Link]();
});

// All data received


[Link]('end', () => {
try {
const data = [Link](body);
[Link](200, { 'Content-Type': 'application/json' });
[Link]([Link]({ received: data }));
} catch (error) {
[Link](400, { 'Content-Type': 'text/plain' });
[Link]('Invalid JSON');
}
});
} else {
[Link](405);
[Link]('Method Not Allowed');
}
});

// ========== HTTP Client (Making Requests) ==========

// GET request
[Link]('[Link] (res) => {
let data = '';

[Link]('data', (chunk) => {


data += chunk;
});

[Link]('end', () => {
[Link]('Response:', data);
});
}).on('error', (error) => {
[Link]('Error:', error);
});

Mistakes to Avoid
❌ Mistake 1: Not calling [Link]()

javascript

// Bad: Response never completes, hangs


const server = [Link]((req, res) => {
[Link](200);
[Link]('Hello');
// Missing [Link]()
});

✅ Correct: Always end the response


javascript

// Good: Response completes


const server = [Link]((req, res) => {
[Link](200);
[Link]('Hello');
});

9. [Link] Introduction
Theory
What is [Link]?
Minimal and flexible [Link] web application framework
Built on top of [Link] HTTP module
Provides robust set of features for web and mobile applications
De facto standard for [Link] web development
Unopinionated (doesn't enforce structure)

Key Features:
Routing system
Middleware support
Template engine integration
Static file serving
Error handling
RESTful API support
Easy integration with databases

Core Concepts:
Application: Express application instance
Request: HTTP request object (enhanced)
Response: HTTP response object (enhanced)
Middleware: Functions that have access to req, res, and next
Router: Modular route handlers

Code Example

javascript
// ========== Installation ==========
// npm install express

// ========== Basic Express App ==========


const express = require('express');
const app = express();

// Simple route
[Link]('/', (req, res) => {
[Link]('Hello World!');
});

// Start server
[Link](3000, () => {
[Link]('Server running on [Link]
});

// ========== Different Response Methods ==========

[Link]('/json', (req, res) => {


[Link]({ message: 'JSON response', status: 'success' });
});

[Link]('/status', (req, res) => {


[Link](201).json({ message: 'Created' });
});

[Link]('/redirect', (req, res) => {


[Link]('/new-location');
});

// ========== Body Parsing ==========

// Parse JSON bodies


[Link]([Link]());

// Parse URL-encoded bodies (form data)


[Link]([Link]({ extended: true }));

// Access parsed body


[Link]('/user', (req, res) => {
[Link]('Body:', [Link]);
[Link]({ received: [Link] });
});

// ========== Static Files ==========


// Serve static files from 'public' directory
[Link]([Link]('public'));

// ========== Complete Example ==========

const express = require('express');


const app = express();

// Middleware
[Link]([Link]());
[Link]([Link]('public'));

// Routes
[Link]('/', (req, res) => {
[Link]('Home Page');
});

[Link]('/api/users', (req, res) => {


[Link]([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]);
});

[Link]('/api/users', (req, res) => {


const user = [Link];
[Link](201).json({ id: 3, ...user });
});

// 404 handler
[Link]((req, res) => {
[Link](404).send('Page not found');
});

// Error handler
[Link]((err, req, res, next) => {
[Link]([Link]);
[Link](500).send('Something broke!');
});

// Start server
const PORT = [Link] || 3000;
[Link](PORT, () => {
[Link](`Server running on port ${PORT}`);
});
Mistakes to Avoid
❌ Mistake 1: Not using middleware for body parsing

javascript

// Bad: [Link] is undefined


[Link]('/user', (req, res) => {
[Link]([Link]); // undefined
});

✅ Correct: Use body parsing middleware

javascript

// Good: Parse request bodies


[Link]([Link]());
[Link]([Link]({ extended: true }));

10. Express Routing


Theory
Routing:
Determining how an application responds to client requests
Consists of URI (path) and HTTP method
Can have one or more handler functions
Supports route parameters, query strings, and wildcards

Route Methods:
[Link]() : GET requests
[Link]() : POST requests
[Link]() : PUT requests
[Link]() : DELETE requests
[Link]() : PATCH requests
[Link]() : All HTTP methods
[Link]() : Middleware

Route Parameters:
Dynamic segments in URL path
Accessed via [Link]
Example: /users/:id

Query Strings:
Key-value pairs in URL
Accessed via [Link]
Example: /search?q=nodejs&page=1

Express Router:
Modular route handlers
Mini Express application
Can be mounted at specific paths

Code Example

javascript
// ========== Basic Routes ==========
const express = require('express');
const app = express();

// GET route
[Link]('/users', (req, res) => {
[Link]({ users: ['Alice', 'Bob'] });
});

// POST route
[Link]('/users', (req, res) => {
[Link](201).json({ message: 'User created' });
});

// PUT route
[Link]('/users/:id', (req, res) => {
[Link]({ message: 'User updated' });
});

// DELETE route
[Link]('/users/:id', (req, res) => {
[Link](204).send();
});

// ========== Route Parameters ==========

[Link]('/users/:id', (req, res) => {


const userId = [Link];
[Link]({ userId });
});

// Multiple parameters
[Link]('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = [Link];
[Link]({ userId, postId });
});

// Optional parameters
[Link]('/users/:id?', (req, res) => {
if ([Link]) {
[Link]({ id: [Link] });
} else {
[Link]({ message: 'All users' });
}
});
// ========== Query Strings ==========

[Link]('/search', (req, res) => {


// URL: /search?q=nodejs&page=2&limit=10
const { q, page, limit } = [Link];

[Link]({
query: q,
page: parseInt(page) || 1,
limit: parseInt(limit) || 10
});
});

// ========== Route Handlers ==========

// Single handler
[Link]('/single', (req, res) => {
[Link]('Single handler');
});

// Multiple handlers
[Link]('/multiple',
(req, res, next) => {
[Link]('First handler');
next();
},
(req, res) => {
[Link]('Second handler');
}
);

// Array of handlers
const handler1 = (req, res, next) => {
[Link]('Handler 1');
next();
};

const handler2 = (req, res, next) => {


[Link]('Handler 2');
next();
};

const handler3 = (req, res) => {


[Link]('Final handler');
};

[Link]('/array', [handler1, handler2, handler3]);


// ========== Express Router ==========

const express = require('express');


const router = [Link]();

// Router-level middleware
[Link]((req, res, next) => {
[Link]('Router middleware');
next();
});

// Define routes
[Link]('/', (req, res) => {
[Link]({ message: 'User list' });
});

[Link]('/:id', (req, res) => {


[Link]({ id: [Link] });
});

[Link]('/', (req, res) => {


[Link](201).json({ message: 'User created' });
});

[Link]('/:id', (req, res) => {


[Link]({ message: 'User updated' });
});

[Link]('/:id', (req, res) => {


[Link](204).send();
});

// Mount router
[Link]('/api/users', router);

// ========== Modular Routes (Separate Files) ==========

// routes/[Link]
const express = require('express');
const router = [Link]();

[Link]('/', (req, res) => {


[Link]({ users: [] });
});

[Link]('/', (req, res) => {


[Link](201).json({ message: 'User created' });
});

[Link] = router;

// [Link]
const userRoutes = require('./routes/users');
[Link]('/api/users', userRoutes);

// ========== Route Patterns ==========

// Wildcards
[Link]('/files/*', (req, res) => {
[Link]('File route');
});

// Regular expressions
[Link](/.*fly$/, (req, res) => {
[Link]('butterfly, dragonfly, etc.');
});

// ========== All HTTP Methods ==========

[Link]('/secret', (req, res) => {


[Link]('Accessing secret');
[Link]('Secret area');
});

// ========== Route Chaining ==========

[Link]('/book')
.get((req, res) => {
[Link]('Get a book');
})
.post((req, res) => {
[Link]('Add a book');
})
.put((req, res) => {
[Link]('Update a book');
});

// ========== Nested Routers ==========

const apiRouter = [Link]();


const usersRouter = [Link]();
const postsRouter = [Link]();
[Link]('/', (req, res) => {
[Link]({ users: [] });
});

[Link]('/', (req, res) => {


[Link]({ posts: [] });
});

[Link]('/users', usersRouter);
[Link]('/posts', postsRouter);

[Link]('/api', apiRouter);
// Routes: /api/users, /api/posts

// ========== Practical Example: REST API Structure ==========

// routes/api/[Link]
const express = require('express');
const router = [Link]();

const userRoutes = require('./users');


const postRoutes = require('./posts');
const commentRoutes = require('./comments');

[Link]('/users', userRoutes);
[Link]('/posts', postRoutes);
[Link]('/comments', commentRoutes);

[Link] = router;

// [Link]
const apiRoutes = require('./routes/api');
[Link]('/api/v1', apiRoutes);

Mistakes to Avoid
❌ Mistake 1: Not using route parameters correctly

javascript

// Bad: Mixing route params and query strings


[Link]('/users?id=:id', (req, res) => {
// This doesn't work
});

✅ Correct: Use route params or query strings, not both


javascript

// Good: Route parameter


[Link]('/users/:id', (req, res) => {
const id = [Link];
});

// Or query string
[Link]('/users', (req, res) => {
const id = [Link];
});

❌ Mistake 2: Forgetting to call next() in middleware

javascript

// Bad: Request hangs


[Link]('/user',
(req, res, next) => {
[Link]('Middleware');
// Forgot next()
},
(req, res) => {
[Link]('User');
}
);

✅ Correct: Always call next() to pass control

javascript

// Good: Call next()


[Link]('/user',
(req, res, next) => {
[Link]('Middleware');
next();
},
(req, res) => {
[Link]('User');
}
);

11. Middleware
Theory
What is Middleware?
Functions that have access to req, res, and next
Execute in sequence
Can modify req and res objects
Can end request-response cycle
Can call next middleware

Types of Middleware:
1. Application-level: Bound to app instance with [Link]() or [Link]()
2. Router-level: Bound to router instance
3. Error-handling: Has 4 parameters (err, req, res, next)
4. Built-in: Express built-in middleware ([Link](), [Link]())
5. Third-party: Installed via npm (morgan, cors, helmet)

Middleware Signature:

javascript

function middleware(req, res, next) {


// Do something
next(); // Pass to next middleware
}

Error-Handling Middleware:

javascript

function errorHandler(err, req, res, next) {


// Handle error
[Link](500).send('Error!');
}

Code Example

javascript
// ========== Application-Level Middleware ==========
const express = require('express');
const app = express();

// Middleware that runs for all routes


[Link]((req, res, next) => {
[Link](`${[Link]} ${[Link]}`);
next();
});

// Middleware for specific path


[Link]('/admin', (req, res, next) => {
[Link]('Admin area');
next();
});

// ========== Built-in Middleware ==========

// Parse JSON bodies


[Link]([Link]());

// Parse URL-encoded bodies


[Link]([Link]({ extended: true }));

// Serve static files


[Link]([Link]('public'));

// ========== Third-Party Middleware ==========

// Morgan - HTTP request logger


const morgan = require('morgan');
[Link](morgan('dev'));

// CORS - Cross-Origin Resource Sharing


const cors = require('cors');
[Link](cors());

// Helmet - Security headers


const helmet = require('helmet');
[Link](helmet());

// Cookie Parser
const cookieParser = require('cookie-parser');
[Link](cookieParser());

// Compression
const compression = require('compression');
[Link](compression());

// ========== Custom Middleware ==========

// Logging middleware
const logger = (req, res, next) => {
[Link](`[${new Date().toISOString()}] ${[Link]} ${[Link]}`);
next();
};

[Link](logger);

// Authentication middleware
const authenticate = (req, res, next) => {
const token = [Link];

if (token === 'secret-token') {


[Link] = { id: 1, name: 'John' };
next();
} else {
[Link](401).json({ error: 'Unauthorized' });
}
};

// Use on specific routes


[Link]('/protected', authenticate, (req, res) => {
[Link]({ user: [Link] });
});

// ========== Error-Handling Middleware ==========

// Regular error handler


[Link]((err, req, res, next) => {
[Link]([Link]);
[Link](500).json({
error: 'Internal Server Error',
message: [Link]
});
});

// 404 handler (must be last)


[Link]((req, res) => {
[Link](404).json({
error: 'Not Found',
path: [Link]
});
});

// ========== Router-Level Middleware ==========

const router = [Link]();

// Router middleware
[Link]((req, res, next) => {
[Link]('Router middleware');
next();
});

[Link]('/', (req, res) => {


[Link]('Router route');
});

[Link]('/api', router);

// ========== Conditional Middleware ==========

const conditionalMiddleware = (req, res, next) => {


if ([Link]) {
[Link]('Debug mode enabled');
}
next();
};

[Link](conditionalMiddleware);

// ========== Async Middleware ==========

const asyncMiddleware = fn => (req, res, next) => {


[Link](fn(req, res, next)).catch(next);
};

[Link]('/async', asyncMiddleware(async (req, res) => {


const data = await fetchData();
[Link](data);
}));

// ========== Practical Examples ==========

// 1. Request timing middleware


[Link]((req, res, next) => {
[Link] = [Link]();

[Link]('finish', () => {
const duration = [Link]() - [Link];
[Link](`${[Link]} ${[Link]} - ${duration}ms`);
});

next();
});

// 2. Request ID middleware
const { v4: uuidv4 } = require('uuid');

[Link]((req, res, next) => {


[Link] = uuidv4();
[Link]('X-Request-ID', [Link]);
next();
});

// 3. Rate limiting middleware


const rateLimit = require('express-rate-limit');

const limiter = rateLimit({


windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});

[Link]('/api/', limiter);

// 4. Body size limit


[Link]([Link]({ limit: '10mb' }));

// 5. Request validation middleware


const validateUser = (req, res, next) => {
const { name, email } = [Link];

if (!name || !email) {
return [Link](400).json({
error: 'Name and email are required'
});
}

if (![Link]('@')) {
return [Link](400).json({
error: 'Invalid email format'
});
}

next();
};
[Link]('/users', validateUser, (req, res) => {
[Link](201).json({ message: 'User created' });
});

// 6. Response modification middleware


[Link]((req, res, next) => {
const originalJson = [Link];

[Link] = function(data) {
const wrappedData = {
success: true,
data: data,
timestamp: new Date().toISOString()
};

return [Link](this, wrappedData);


};

next();
});

Mistakes to Avoid
❌ Mistake 1: Not calling next()

javascript

// Bad: Request hangs


[Link]((req, res, next) => {
[Link]('Middleware');
// Forgot next()
});

✅ Correct: Always call next() unless ending response

javascript

// Good: Call next()


[Link]((req, res, next) => {
[Link]('Middleware');
next();
});

❌ Mistake 2: Wrong order of middleware

javascript
// Bad: Routes before body parser
[Link]('/user', (req, res) => {
[Link]([Link]); // undefined
});

[Link]([Link]());

✅ Correct: Middleware before routes

javascript

// Good: Body parser first


[Link]([Link]());

[Link]('/user', (req, res) => {


[Link]([Link]); // Works
});

Continuing with more topics...

12. Request and Response Objects


Theory
Request Object (req):
Contains information about HTTP request
Enhanced version of [Link] [Link]
Common properties and methods

Request Properties:
[Link] : Route parameters
[Link] : Query string parameters
[Link] : Request body (requires middleware)
[Link] : Request headers
[Link] : HTTP method
[Link] : Request URL
[Link] : Path portion of URL
[Link] : Host name
[Link] : Remote IP address
[Link] : Cookies (requires cookie-parser)

Response Object (res):


Send response back to client
Enhanced version of [Link] [Link]
Common properties and methods

Response Methods:
[Link]() : Send various types of responses
[Link]() : Send JSON response
[Link]() : Set status code
[Link]() : Redirect to URL
[Link]() : Render view template
[Link]() : Send file
[Link]() : Prompt file download
[Link]() : Set cookie
[Link]() : Clear cookie

Code Example

javascript
// ========== Request Properties ==========
const express = require('express');
const app = express();

[Link]([Link]());

[Link]('/user/:id', (req, res) => {


// Route parameters
[Link]([Link]); // { id: '123' }
const userId = [Link];

// Query strings (?name=John&age=30)


[Link]([Link]); // { name: 'John', age: '30' }
const { name, age } = [Link];

// Headers
[Link]([Link]);
const userAgent = [Link]('User-Agent');
const contentType = [Link]('Content-Type');

// Method
[Link]([Link]); // GET

// URL and path


[Link]([Link]); // /user/123?name=John
[Link]([Link]); // /user/123
[Link]([Link]); // Full URL

// Protocol and security


[Link]([Link]); // http or https
[Link]([Link]); // true for HTTPS

// IP address
[Link]([Link]); // Client IP
[Link]([Link]); // Array of IPs (if behind proxy)

// Hostname
[Link]([Link]); // [Link]
[Link]([Link]); // ['api'] for [Link]

[Link]({ message: 'Request info logged' });


});

[Link]('/login', (req, res) => {


// Request body (requires [Link]())
[Link]([Link]); // { username: 'john', password: 'secret' }
const { username, password } = [Link];

[Link]({ success: true });


});

// ========== Request Methods ==========

// Check if request accepts certain type


[Link]('/data', (req, res) => {
if ([Link]('json')) {
[Link]({ data: 'JSON response' });
} else if ([Link]('html')) {
[Link]('<h1>HTML response</h1>');
} else {
[Link](406).send('Not Acceptable');
}
});

// Check content type


[Link]('/upload', (req, res) => {
if ([Link]('application/json')) {
[Link]('JSON data received');
} else if ([Link]('multipart/form-data')) {
[Link]('Form data received');
}

[Link]('Uploaded');
});

// ========== Response Methods ==========

// Send text
[Link]('/text', (req, res) => {
[Link]('Plain text response');
});

// Send JSON
[Link]('/json', (req, res) => {
[Link]({
user: 'John',
age: 30,
active: true
});
});

// Send status code


[Link]('/created', (req, res) => {
[Link](201).json({ message: 'Resource created' });
});

// Chain methods
[Link]('/chain', (req, res) => {
res
.status(200)
.set('Content-Type', 'application/json')
.json({ message: 'Chained response' });
});

// Send file
const path = require('path');

[Link]('/file', (req, res) => {


const filePath = [Link](__dirname, 'public', '[Link]');
[Link](filePath);
});

// Download file
[Link]('/download', (req, res) => {
const filePath = [Link](__dirname, 'files', '[Link]');
[Link](filePath, '[Link]', (err) => {
if (err) {
[Link]('Download error:', err);
}
});
});

// Redirect
[Link]('/old-route', (req, res) => {
[Link]('/new-route');
});

// Redirect with status code


[Link]('/moved', (req, res) => {
[Link](301, '[Link]
});

// ========== Headers ==========

// Set single header


[Link]('/header', (req, res) => {
[Link]('X-Custom-Header', 'CustomValue');
[Link]('Header set');
});
// Set multiple headers
[Link]('/headers', (req, res) => {
[Link]({
'X-Custom-Header': 'Value1',
'X-Another-Header': 'Value2',
'Cache-Control': 'no-cache'
});
[Link]('Headers set');
});

// Get header
[Link]('/check-header', (req, res) => {
const auth = [Link]('Authorization');
[Link]({ auth });
});

// ========== Cookies ==========

const cookieParser = require('cookie-parser');


[Link](cookieParser());

// Set cookie
[Link]('/set-cookie', (req, res) => {
[Link]('user', 'john', {
maxAge: 900000, // 15 minutes
httpOnly: true,
secure: true,
sameSite: 'strict'
});
[Link]('Cookie set');
});

// Get cookies
[Link]('/get-cookies', (req, res) => {
[Link]([Link]); // { user: 'john' }
[Link]([Link]);
});

// Clear cookie
[Link]('/clear-cookie', (req, res) => {
[Link]('user');
[Link]('Cookie cleared');
});

// ========== Response Status Codes ==========

// Success
[Link]('/success', (req, res) => {
[Link](200).json({ message: 'OK' });
});

[Link]('/created', (req, res) => {


[Link](201).json({ message: 'Created' });
});

[Link]('/deleted', (req, res) => {


[Link](204).send(); // No Content
});

// Client Errors
[Link]('/bad-request', (req, res) => {
[Link](400).json({ error: 'Bad Request' });
});

[Link]('/unauthorized', (req, res) => {


[Link](401).json({ error: 'Unauthorized' });
});

[Link]('/forbidden', (req, res) => {


[Link](403).json({ error: 'Forbidden' });
});

[Link]('/not-found', (req, res) => {


[Link](404).json({ error: 'Not Found' });
});

// Server Errors
[Link]('/server-error', (req, res) => {
[Link](500).json({ error: 'Internal Server Error' });
});

// ========== Content Negotiation ==========

[Link]('/content-negotiation', (req, res) => {


[Link]({
'text/plain': () => {
[Link]('Plain text');
},
'text/html': () => {
[Link]('<h1>HTML response</h1>');
},
'application/json': () => {
[Link]({ message: 'JSON response' });
},
default: () => {
[Link](406).send('Not Acceptable');
}
});
});

// ========== Streaming Response ==========

[Link]('/stream', (req, res) => {


[Link]('Content-Type', 'text/plain');
[Link]('Chunk 1\n');

setTimeout(() => {
[Link]('Chunk 2\n');
}, 1000);

setTimeout(() => {
[Link]('Final chunk\n');
}, 2000);
});

Mistakes to Avoid
❌ Mistake 1: Sending response multiple times

javascript

// Bad: Can't send response twice


[Link]('/user', (req, res) => {
[Link]('First');
[Link]('Second'); // Error!
});

✅ Correct: Send response once

javascript

// Good: Single response


[Link]('/user', (req, res) => {
[Link]({ user: 'John' });
});

❌ Mistake 2: Not checking if response was sent

javascript
// Bad: Might send response twice
[Link]('/data', (req, res) => {
if (error) {
[Link](500).json({ error });
}
[Link]({ data }); // Sent even if error
});

✅ Correct: Use return or check [Link]

javascript

// Good: Return after sending


[Link]('/data', (req, res) => {
if (error) {
return [Link](500).json({ error });
}
[Link]({ data });
});

13. Template Engines


Theory
Template Engines:
Generate HTML dynamically
Embed JavaScript logic in HTML
Popular engines: EJS, Pug, Handlebars
Support layouts, partials, and helpers

EJS (Embedded JavaScript):


Uses <% %> tags
Simple and familiar syntax
Extension: .ejs

Pug (formerly Jade):


Indentation-based
No closing tags
Clean syntax
Extension: .pug
Handlebars:
Logic-less templates
Mustache compatible
Extension: .hbs

Code Example

javascript
// ========== Setting Up Template Engine ==========
const express = require('express');
const app = express();

// Set view engine


[Link]('view engine', 'ejs');

// Set views directory


[Link]('views', [Link](__dirname, 'views'));

// ========== Using EJS ==========

// views/[Link]
/*
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1>Welcome <%= name %>!</h1>

<% if (loggedIn) { %>


<p>You are logged in</p>
<% } else { %>
<p>Please log in</p>
<% } %>

<ul>
<% [Link](user => { %>
<li><%= [Link] %></li>
<% }); %>
</ul>
</body>
</html>
*/

// Route
[Link]('/', (req, res) => {
[Link]('index', {
title: 'Home Page',
name: 'John',
loggedIn: true,
users: [
{ name: 'Alice' },
{ name: 'Bob' },
{ name: 'Charlie' }
]
});
});

// ========== EJS Partials ==========

// views/partials/[Link]
/*
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
*/

// views/[Link]
/*
<%- include('partials/header') %>
<main>
<h1>Main Content</h1>
</main>
<%- include('partials/footer') %>
*/

// ========== Using Pug ==========

// Install: npm install pug


[Link]('view engine', 'pug');

// views/[Link]
/*
doctype html
html
head
title= title
body
h1 Welcome #{name}!

if loggedIn
p You are logged in
else
p Please log in

ul
each user in users
li= [Link]
*/

// Route
[Link]('/pug', (req, res) => {
[Link]('index', {
title: 'Pug Page',
name: 'John',
loggedIn: true,
users: [
{ name: 'Alice' },
{ name: 'Bob' }
]
});
});

// ========== Using Handlebars ==========

// Install: npm install express-handlebars


const { engine } = require('express-handlebars');

[Link]('hbs', engine({
extname: '.hbs',
defaultLayout: 'main',
layoutsDir: [Link](__dirname, 'views', 'layouts'),
partialsDir: [Link](__dirname, 'views', 'partials')
}));

[Link]('view engine', 'hbs');

// views/layouts/[Link]
/*
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
{{{body}}}
</body>
</html>
*/

// views/[Link]
/*
<h1>Welcome {{name}}!</h1>
{{#if loggedIn}}
<p>You are logged in</p>
{{else}}
<p>Please log in</p>
{{/if}}

<ul>
{{#each users}}
<li>{{[Link]}}</li>
{{/each}}
</ul>
*/

// Route
[Link]('/hbs', (req, res) => {
[Link]('index', {
title: 'Handlebars Page',
name: 'John',
loggedIn: true,
users: [
{ name: 'Alice' },
{ name: 'Bob' }
]
});
});

// ========== Custom Helpers (Handlebars) ==========

[Link]('hbs', engine({
extname: '.hbs',
helpers: {
uppercase: (str) => [Link](),
formatDate: (date) => new Date(date).toLocaleDateString(),
times: (n, block) => {
let result = '';
for (let i = 0; i < n; i++) {
result += [Link](i);
}
return result;
}
}
}));

// Use in template: {{uppercase name}}


Mistakes to Avoid
❌ Mistake 1: Not escaping user input

javascript

// Bad: XSS vulnerability


// <%= userInput %> // In EJS, this is actually safe
// {{{ userInput }}} // In Handlebars, this is unsafe!

✅ Correct: Always escape unless intentional

javascript

// Good: Escaped output


// <%= userInput %> // EJS - escaped by default
// {{userInput}} // Handlebars - escaped by default

14. Error Handling


Theory
Error Handling in Express:
Synchronous errors caught automatically
Async errors must be passed to next()
Error-handling middleware has 4 parameters
Error middleware must be defined last

Error Types:
Operational errors: Expected errors (validation, network)
Programmer errors: Bugs in code
System errors: OS/environment errors

Best Practices:
Use custom error classes
Centralized error handling
Log errors appropriately
Return appropriate status codes
Don't expose sensitive information
Code Example

javascript
// ========== Basic Error Handling ==========
const express = require('express');
const app = express();

// Synchronous error (caught automatically)


[Link]('/sync-error', (req, res) => {
throw new Error('Synchronous error'); // Caught by Express
});

// Asynchronous error (must pass to next)


[Link]('/async-error', (req, res, next) => {
setTimeout(() => {
try {
throw new Error('Async error');
} catch (error) {
next(error); // Pass to error handler
}
}, 100);
});

// Async/await error handling


[Link]('/await-error', async (req, res, next) => {
try {
await someAsyncOperation();
[Link]({ success: true });
} catch (error) {
next(error);
}
});

// ========== Custom Error Class ==========

class AppError extends Error {


constructor(message, statusCode) {
super(message);
[Link] = statusCode;
[Link] = true;

[Link](this, [Link]);
}
}

// Usage
[Link]('/not-found', (req, res, next) => {
next(new AppError('Resource not found', 404));
});
[Link]('/unauthorized', (req, res, next) => {
next(new AppError('Not authorized', 401));
});

// ========== Error-Handling Middleware ==========

// Must have 4 parameters (err, req, res, next)


[Link]((err, req, res, next) => {
[Link]([Link]);

const statusCode = [Link] || 500;


const message = [Link] || 'Internal Server Error';

[Link](statusCode).json({
status: 'error',
statusCode,
message,
...([Link].NODE_ENV === 'development' && { stack: [Link] })
});
});

// ========== Multiple Error Handlers ==========

// Logging error handler


[Link]((err, req, res, next) => {
[Link](`[${new Date().toISOString()}] ${[Link]}`);
next(err); // Pass to next error handler
});

// Client error handler


[Link]((err, req, res, next) => {
if ([Link]) {
[Link](500).json({ error: 'Something failed!' });
} else {
next(err);
}
});

// Catch-all error handler


[Link]((err, req, res, next) => {
[Link](500).send('Internal Server Error');
});

// ========== Async Error Wrapper ==========

const asyncHandler = fn => (req, res, next) => {


[Link](fn(req, res, next)).catch(next);
};

[Link]('/users', asyncHandler(async (req, res) => {


const users = await [Link]();
[Link](users);
}));

// ========== Validation Errors ==========

const { body, validationResult } = require('express-validator');

[Link]('/user',
body('email').isEmail(),
body('password').isLength({ min: 6 }),
(req, res, next) => {
const errors = validationResult(req);

if (![Link]()) {
return [Link](400).json({
status: 'error',
errors: [Link]()
});
}

[Link]({ message: 'User created' });


}
);

// ========== 404 Handler ==========

// Must be after all routes


[Link]((req, res, next) => {
[Link](404).json({
status: 'error',
message: 'Route not found',
path: [Link]
});
});

// ========== Production vs Development Errors ==========

[Link]((err, req, res, next) => {


if ([Link].NODE_ENV === 'production') {
// Don't leak error details in production
if ([Link]) {
[Link]([Link]).json({
status: 'error',
message: [Link]
});
} else {
// Log programmer errors
[Link]('ERROR 💥', err);
[Link](500).json({
status: 'error',
message: 'Something went wrong'
});
}
} else {
// Send full error in development
[Link]([Link] || 500).json({
status: 'error',
message: [Link],
stack: [Link],
error: err
});
}
});

// ========== Centralized Error Handler ==========

// errors/[Link]
class AppError extends Error {
constructor(message, statusCode) {
super(message);
[Link] = statusCode;
[Link] = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
[Link] = true;

[Link](this, [Link]);
}
}

[Link] = AppError;

// middleware/[Link]
const errorHandler = (err, req, res, next) => {
[Link] = [Link] || 500;
[Link] = [Link] || 'error';

if ([Link].NODE_ENV === 'development') {


sendErrorDev(err, res);
} else {
sendErrorProd(err, res);
}
};

const sendErrorDev = (err, res) => {


[Link]([Link]).json({
status: [Link],
error: err,
message: [Link],
stack: [Link]
});
};

const sendErrorProd = (err, res) => {


if ([Link]) {
[Link]([Link]).json({
status: [Link],
message: [Link]
});
} else {
[Link]('ERROR 💥', err);
[Link](500).json({
status: 'error',
message: 'Something went wrong'
});
}
};

[Link] = errorHandler;

Mistakes to Avoid
❌ Mistake 1: Not passing async errors to next()

javascript

// Bad: Unhandled promise rejection


[Link]('/users', async (req, res) => {
const users = await [Link](); // Can throw error
[Link](users);
});

✅ Correct: Use try-catch or async handler

javascript
// Good: Proper error handling
[Link]('/users', async (req, res, next) => {
try {
const users = await [Link]();
[Link](users);
} catch (error) {
next(error);
}
});

15. Database Integration


Theory
Database Options:
MongoDB: NoSQL, document database (Mongoose ODM)
PostgreSQL: Relational database (Sequelize, Knex)
MySQL: Relational database (Sequelize, Knex)
Redis: In-memory key-value store
SQLite: File-based relational database

Mongoose (MongoDB):
Object Data Modeling (ODM) library
Schema-based solution
Built-in validation
Middleware support
Query building

Sequelize (SQL):
Promise-based ORM
Supports MySQL, PostgreSQL, SQLite, MSSQL
Migrations and seeders
Associations and transactions

Code Example

javascript
// ========== MongoDB with Mongoose ==========

// Install: npm install mongoose

const mongoose = require('mongoose');

// Connect to MongoDB
[Link]('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => [Link]('MongoDB connected'))
.catch(err => [Link]('MongoDB connection error:', err));

// Define Schema
const userSchema = new [Link]({
name: {
type: String,
required: [true, 'Name is required'],
trim: true,
minlength: 3,
maxlength: 50
},
email: {
type: String,
required: true,
unique: true,
lowercase: true,
validate: {
validator: (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email),
message: 'Invalid email format'
}
},
age: {
type: Number,
min: 0,
max: 120
},
password: {
type: String,
required: true,
minlength: 6,
select: false // Don't include in queries by default
},
role: {
type: String,
enum: ['user', 'admin'],
default: 'user'
},
active: {
type: Boolean,
default: true
},
createdAt: {
type: Date,
default: [Link]
}
});

// Create Model
const User = [Link]('User', userSchema);

// ========== CRUD Operations ==========

// Create
[Link]('/users', async (req, res, next) => {
try {
const user = await [Link]([Link]);
[Link](201).json({ user });
} catch (error) {
next(error);
}
});

// Read all
[Link]('/users', async (req, res, next) => {
try {
const users = await [Link]();
[Link]({ users });
} catch (error) {
next(error);
}
});

// Read one
[Link]('/users/:id', async (req, res, next) => {
try {
const user = await [Link]([Link]);

if (!user) {
return [Link](404).json({ error: 'User not found' });
}
[Link]({ user });
} catch (error) {
next(error);
}
});

// Update
[Link]('/users/:id', async (req, res, next) => {
try {
const user = await [Link](
[Link],
[Link],
{ new: true, runValidators: true }
);

if (!user) {
return [Link](404).json({ error: 'User not found' });
}

[Link]({ user });


} catch (error) {
next(error);
}
});

// Delete
[Link]('/users/:id', async (req, res, next) => {
try {
const user = await [Link]([Link]);

if (!user) {
return [Link](404).json({ error: 'User not found' });
}

[Link](204).send();
} catch (error) {
next(error);
}
});

// ========== Query Building ==========

[Link]('/users/search', async (req, res, next) => {


try {
const { name, minAge, maxAge, role } = [Link];

const query = {};


if (name) {
[Link] = new RegExp(name, 'i'); // Case-insensitive
}

if (minAge || maxAge) {
[Link] = {};
if (minAge) [Link].$gte = parseInt(minAge);
if (maxAge) [Link].$lte = parseInt(maxAge);
}

if (role) {
[Link] = role;
}

const users = await [Link](query)


.select('name email age')
.sort({ createdAt: -1 })
.limit(10)
.skip(0);

[Link]({ users });


} catch (error) {
next(error);
}
});

// ========== Mongoose Middleware ==========

// Pre-save middleware
[Link]('save', async function(next) {
// Hash password before saving
if (![Link]('password')) return next();

const bcrypt = require('bcryptjs');


[Link] = await [Link]([Link], 12);
next();
});

// Instance method
[Link] = async function(candidatePassword) {
const bcrypt = require('bcryptjs');
return await [Link](candidatePassword, [Link]);
};

// Static method
[Link] = function(email) {
return [Link]({ email });
};

// ========== PostgreSQL with Sequelize ==========

// Install: npm install sequelize pg pg-hstore

const { Sequelize, DataTypes } = require('sequelize');

// Connect to PostgreSQL
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'postgres',
logging: false
});

// Define Model
const User = [Link]('User', {
name: {
type: [Link],
allowNull: false,
validate: {
len: [3, 50]
}
},
email: {
type: [Link],
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
age: {
type: [Link],
validate: {
min: 0,
max: 120
}
},
password: {
type: [Link],
allowNull: false,
validate: {
len: [6, 100]
}
},
role: {
type: [Link]('user', 'admin'),
defaultValue: 'user'
}
});

// Sync database
[Link]({ alter: true })
.then(() => [Link]('Database synced'))
.catch(err => [Link]('Sync error:', err));

// CRUD with Sequelize


[Link]('/users', async (req, res, next) => {
try {
const user = await [Link]([Link]);
[Link](201).json({ user });
} catch (error) {
next(error);
}
});

[Link]('/users', async (req, res, next) => {


try {
const users = await [Link]({
attributes: ['id', 'name', 'email', 'age'],
where: { active: true },
order: [['createdAt', 'DESC']],
limit: 10
});
[Link]({ users });
} catch (error) {
next(error);
}
});

Mistakes to Avoid
❌ Mistake 1: Not handling validation errors

javascript

// Bad: No validation
const user = await [Link]([Link]);

✅ Correct: Handle validation errors

javascript
// Good: Proper validation
try {
const user = await [Link]([Link]);
[Link](201).json({ user });
} catch (error) {
if ([Link] === 'ValidationError') {
return [Link](400).json({ errors: [Link] });
}
next(error);
}

Continuing with Authentication, REST APIs, Security, Testing, Performance, and Deployment...

16. Authentication and Authorization


Theory
Authentication vs Authorization:
Authentication: Verifying who the user is (login)
Authorization: Verifying what the user can do (permissions)

Authentication Methods:
Session-based: Server stores session, client gets cookie
Token-based (JWT): Stateless, client stores token
OAuth: Third-party authentication (Google, Facebook)
API Keys: Simple key for API access

JWT (JSON Web Tokens):


Self-contained tokens
Contains user info and signature
Stateless (no server storage)
Structure: [Link]

Security Best Practices:


Hash passwords (bcrypt)
Use HTTPS
Implement rate limiting
Validate all inputs
Set secure HTTP headers

Code Example

javascript
// ========== Session-Based Authentication ==========

// Install: npm install express-session

const session = require('express-session');

[Link](session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 1000 * 60 * 60 * 24, // 1 day
httpOnly: true,
secure: [Link].NODE_ENV === 'production', // HTTPS only
sameSite: 'strict'
}
}));

// Login route
[Link]('/login', async (req, res) => {
const { email, password } = [Link];

const user = await [Link]({ email }).select('+password');

if (!user || !(await [Link](password))) {


return [Link](401).json({ error: 'Invalid credentials' });
}

[Link] = user._id;
[Link] = [Link];

[Link]({ message: 'Logged in successfully' });


});

// Logout route
[Link]('/logout', (req, res) => {
[Link]((err) => {
if (err) {
return [Link](500).json({ error: 'Logout failed' });
}
[Link]('[Link]');
[Link]({ message: 'Logged out successfully' });
});
});

// Auth middleware
const requireAuth = (req, res, next) => {
if (![Link]) {
return [Link](401).json({ error: 'Not authenticated' });
}
next();
};

// Protected route
[Link]('/profile', requireAuth, async (req, res) => {
const user = await [Link]([Link]);
[Link]({ user });
});

// ========== JWT Authentication ==========

// Install: npm install jsonwebtoken bcryptjs

const jwt = require('jsonwebtoken');


const bcrypt = require('bcryptjs');

const JWT_SECRET = [Link].JWT_SECRET || 'your-secret-key';


const JWT_EXPIRES_IN = '7d';

// Sign up
[Link]('/signup', async (req, res, next) => {
try {
const { name, email, password } = [Link];

// Check if user exists


const existingUser = await [Link]({ email });
if (existingUser) {
return [Link](400).json({ error: 'User already exists' });
}

// Hash password
const hashedPassword = await [Link](password, 12);

// Create user
const user = await [Link]({
name,
email,
password: hashedPassword
});

// Generate token
const token = [Link](
{ id: user._id, email: [Link] },
JWT_SECRET,
{ expiresIn: JWT_EXPIRES_IN }
);

[Link](201).json({
user: {
id: user._id,
name: [Link],
email: [Link]
},
token
});
} catch (error) {
next(error);
}
});

// Login
[Link]('/login', async (req, res, next) => {
try {
const { email, password } = [Link];

// Find user with password


const user = await [Link]({ email }).select('+password');

if (!user) {
return [Link](401).json({ error: 'Invalid credentials' });
}

// Check password
const isPasswordValid = await [Link](password, [Link]);

if (!isPasswordValid) {
return [Link](401).json({ error: 'Invalid credentials' });
}

// Generate token
const token = [Link](
{ id: user._id, email: [Link], role: [Link] },
JWT_SECRET,
{ expiresIn: JWT_EXPIRES_IN }
);

[Link]({
user: {
id: user._id,
name: [Link],
email: [Link],
role: [Link]
},
token
});
} catch (error) {
next(error);
}
});

// JWT Auth middleware


const authenticateJWT = async (req, res, next) => {
try {
// Get token from header
const authHeader = [Link];

if (!authHeader || ![Link]('Bearer ')) {


return [Link](401).json({ error: 'No token provided' });
}

const token = [Link](7);

// Verify token
const decoded = [Link](token, JWT_SECRET);

// Get user from token


const user = await [Link]([Link]);

if (!user) {
return [Link](401).json({ error: 'User not found' });
}

// Add user to request


[Link] = user;
next();
} catch (error) {
if ([Link] === 'JsonWebTokenError') {
return [Link](401).json({ error: 'Invalid token' });
}
if ([Link] === 'TokenExpiredError') {
return [Link](401).json({ error: 'Token expired' });
}
next(error);
}
};

// Protected route
[Link]('/profile', authenticateJWT, (req, res) => {
[Link]({ user: [Link] });
});

// ========== Role-Based Authorization ==========

const authorize = (...roles) => {


return (req, res, next) => {
if (![Link]) {
return [Link](401).json({ error: 'Not authenticated' });
}

if (![Link]([Link])) {
return [Link](403).json({ error: 'Not authorized' });
}

next();
};
};

// Admin-only route
[Link]('/users/:id',
authenticateJWT,
authorize('admin'),
async (req, res, next) => {
try {
await [Link]([Link]);
[Link](204).send();
} catch (error) {
next(error);
}
}
);

// ========== Refresh Tokens ==========

const generateTokens = (user) => {


const accessToken = [Link](
{ id: user._id, email: [Link] },
JWT_SECRET,
{ expiresIn: '15m' }
);

const refreshToken = [Link](


{ id: user._id },
[Link].REFRESH_TOKEN_SECRET,
{ expiresIn: '7d' }
);

return { accessToken, refreshToken };


};

[Link]('/refresh-token', async (req, res, next) => {


try {
const { refreshToken } = [Link];

if (!refreshToken) {
return [Link](401).json({ error: 'No refresh token' });
}

const decoded = [Link](refreshToken, [Link].REFRESH_TOKEN_SECRET);


const user = await [Link]([Link]);

if (!user) {
return [Link](401).json({ error: 'User not found' });
}

const tokens = generateTokens(user);


[Link](tokens);
} catch (error) {
next(error);
}
});

// ========== Password Reset ==========

const crypto = require('crypto');

// Request password reset


[Link]('/forgot-password', async (req, res, next) => {
try {
const { email } = [Link];
const user = await [Link]({ email });

if (!user) {
return [Link](404).json({ error: 'User not found' });
}

// Generate reset token


const resetToken = [Link](32).toString('hex');
const hashedToken = crypto
.createHash('sha256')
.update(resetToken)
.digest('hex');
[Link] = hashedToken;
[Link] = [Link]() + 10 * 60 * 1000; // 10 minutes
await [Link]();

// Send email with reset link (using nodemailer)


const resetUrl = `${[Link]}://${[Link]('host')}/reset-password/${resetTok

// TODO: Send email

[Link]({ message: 'Reset email sent' });


} catch (error) {
next(error);
}
});

// Reset password
[Link]('/reset-password/:token', async (req, res, next) => {
try {
const hashedToken = crypto
.createHash('sha256')
.update([Link])
.digest('hex');

const user = await [Link]({


passwordResetToken: hashedToken,
passwordResetExpires: { $gt: [Link]() }
});

if (!user) {
return [Link](400).json({ error: 'Invalid or expired token' });
}

const { password } = [Link];


[Link] = await [Link](password, 12);
[Link] = undefined;
[Link] = undefined;
await [Link]();

[Link]({ message: 'Password reset successful' });


} catch (error) {
next(error);
}
});

// ========== OAuth 2.0 (Google) ==========


// Install: npm install passport passport-google-oauth20

const passport = require('passport');


const GoogleStrategy = require('passport-google-oauth20').Strategy;

[Link](new GoogleStrategy({
clientID: [Link].GOOGLE_CLIENT_ID,
clientSecret: [Link].GOOGLE_CLIENT_SECRET,
callbackURL: '/auth/google/callback'
},
async (accessToken, refreshToken, profile, done) => {
try {
let user = await [Link]({ googleId: [Link] });

if (!user) {
user = await [Link]({
googleId: [Link],
name: [Link],
email: [Link][0].value
});
}

done(null, user);
} catch (error) {
done(error, null);
}
}
));

[Link]('/auth/google',
[Link]('google', { scope: ['profile', 'email'] })
);

[Link]('/auth/google/callback',
[Link]('google', { session: false }),
(req, res) => {
const token = [Link](
{ id: [Link]._id },
JWT_SECRET,
{ expiresIn: JWT_EXPIRES_IN }
);

[Link](`/auth-success?token=${token}`);
}
);
Mistakes to Avoid
❌ Mistake 1: Storing passwords in plain text

javascript

// Bad: Plain text password


const user = await [Link]({
email,
password: password // Never do this!
});

✅ Correct: Hash passwords

javascript

// Good: Hashed password


const hashedPassword = await [Link](password, 12);
const user = await [Link]({
email,
password: hashedPassword
});

❌ Mistake 2: Not validating JWT properly

javascript

// Bad: No verification
const token = [Link];
const user = [Link](atob([Link]('.')[1]));

✅ Correct: Verify JWT signature

javascript

// Good: Proper verification


const token = [Link](7);
const decoded = [Link](token, JWT_SECRET);

17. RESTful API Design


Theory
REST (Representational State Transfer):
Architectural style for APIs
Uses HTTP methods
Stateless communication
Resource-based URLs
HTTP Methods:
GET: Retrieve resources
POST: Create resources
PUT: Update entire resource
PATCH: Update part of resource
DELETE: Delete resource

Best Practices:
Use nouns for resources (not verbs)
Use HTTP methods for actions
Use proper status codes
Version your API
Implement pagination
Provide filtering and sorting
Use HATEOAS (Hypermedia)

Status Codes:
200: OK
201: Created
204: No Content
400: Bad Request
401: Unauthorized
403: Forbidden
404: Not Found
500: Internal Server Error

Code Example

javascript
// ========== RESTful API Structure ==========

const express = require('express');


const router = [Link]();

// Base URL: /api/v1/users

// GET /api/v1/users - Get all users


[Link]('/', async (req, res, next) => {
try {
const { page = 1, limit = 10, sort = '-createdAt', search } = [Link];

const query = {};


if (search) {
[Link] = new RegExp(search, 'i');
}

const users = await [Link](query)


.select('-password')
.sort(sort)
.limit(parseInt(limit))
.skip((parseInt(page) - 1) * parseInt(limit));

const total = await [Link](query);

[Link]({
status: 'success',
results: [Link],
total,
page: parseInt(page),
pages: [Link](total / parseInt(limit)),
data: { users }
});
} catch (error) {
next(error);
}
});

// GET /api/v1/users/:id - Get single user


[Link]('/:id', async (req, res, next) => {
try {
const user = await [Link]([Link]).select('-password');

if (!user) {
return [Link](404).json({
status: 'fail',
message: 'User not found'
});
}

[Link]({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});

// POST /api/v1/users - Create user


[Link]('/', async (req, res, next) => {
try {
const user = await [Link]([Link]);

[Link](201).json({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});

// PUT /api/v1/users/:id - Update entire user


[Link]('/:id', async (req, res, next) => {
try {
const user = await [Link](
[Link],
[Link],
{ new: true, runValidators: true, overwrite: true }
);

if (!user) {
return [Link](404).json({
status: 'fail',
message: 'User not found'
});
}

[Link]({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});

// PATCH /api/v1/users/:id - Update part of user


[Link]('/:id', async (req, res, next) => {
try {
const user = await [Link](
[Link],
[Link],
{ new: true, runValidators: true }
);

if (!user) {
return [Link](404).json({
status: 'fail',
message: 'User not found'
});
}

[Link]({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});

// DELETE /api/v1/users/:id - Delete user


[Link]('/:id', async (req, res, next) => {
try {
const user = await [Link]([Link]);

if (!user) {
return [Link](404).json({
status: 'fail',
message: 'User not found'
});
}

[Link](204).send();
} catch (error) {
next(error);
}
});
// ========== Nested Resources ==========

// GET /api/v1/users/:userId/posts
[Link]('/:userId/posts', async (req, res, next) => {
try {
const posts = await [Link]({ userId: [Link] });

[Link]({
status: 'success',
results: [Link],
data: { posts }
});
} catch (error) {
next(error);
}
});

// ========== API Versioning ==========

// [Link]
[Link]('/api/v1/users', require('./routes/v1/users'));
[Link]('/api/v2/users', require('./routes/v2/users'));

// ========== Filtering ==========

[Link]('/', async (req, res, next) => {


try {
const { role, active, minAge, maxAge } = [Link];

const filter = {};

if (role) [Link] = role;


if (active !== undefined) [Link] = active === 'true';

if (minAge || maxAge) {
[Link] = {};
if (minAge) [Link].$gte = parseInt(minAge);
if (maxAge) [Link].$lte = parseInt(maxAge);
}

const users = await [Link](filter);


[Link]({ status: 'success', data: { users } });
} catch (error) {
next(error);
}
});
// ========== Sorting ==========

[Link]('/', async (req, res, next) => {


try {
const { sort = '-createdAt' } = [Link];

const users = await [Link]().sort(sort);


[Link]({ status: 'success', data: { users } });
} catch (error) {
next(error);
}
});

// ========== Pagination ==========

[Link]('/', async (req, res, next) => {


try {
const page = parseInt([Link]) || 1;
const limit = parseInt([Link]) || 10;
const skip = (page - 1) * limit;

const users = await [Link]()


.skip(skip)
.limit(limit);

const total = await [Link]();

[Link]({
status: 'success',
results: [Link],
pagination: {
page,
limit,
totalPages: [Link](total / limit),
total
},
data: { users }
});
} catch (error) {
next(error);
}
});

// ========== Field Selection ==========

[Link]('/', async (req, res, next) => {


try {
const { fields } = [Link];

let query = [Link]();

if (fields) {
const selectedFields = [Link](',').join(' ');
query = [Link](selectedFields);
}

const users = await query;


[Link]({ status: 'success', data: { users } });
} catch (error) {
next(error);
}
});

// ========== Rate Limiting ==========

const rateLimit = require('express-rate-limit');

const apiLimiter = rateLimit({


windowMs: 15 * 60 * 1000, // 15 minutes
max: 100,
message: 'Too many requests from this IP'
});

[Link]('/api/', apiLimiter);

// ========== HATEOAS ==========

[Link]('/:id', async (req, res, next) => {


try {
const user = await [Link]([Link]);

if (!user) {
return [Link](404).json({ error: 'User not found' });
}

[Link]({
status: 'success',
data: { user },
links: {
self: `/api/v1/users/${user._id}`,
posts: `/api/v1/users/${user._id}/posts`,
update: `/api/v1/users/${user._id}`,
delete: `/api/v1/users/${user._id}`
}
});
} catch (error) {
next(error);
}
});

Mistakes to Avoid
❌ Mistake 1: Using verbs in URLs

javascript

// Bad: Verbs in URL


[Link]('/api/getUsers')
[Link]('/api/createUser')
[Link]('/api/updateUser/:id')

✅ Correct: Use nouns and HTTP methods

javascript

// Good: Resource-based URLs


[Link]('/api/users')
[Link]('/api/users')
[Link]('/api/users/:id')

❌ Mistake 2: Not using proper status codes

javascript

// Bad: Always 200


[Link]('/users', (req, res) => {
const user = createUser([Link]);
[Link]({ user }); // Should be 201
});

✅ Correct: Use appropriate status codes

javascript

// Good: Proper status codes


[Link]('/users', (req, res) => {
const user = createUser([Link]);
[Link](201).json({ user });
});
18. Security Best Practices
Theory
Common Security Vulnerabilities:
SQL Injection
XSS (Cross-Site Scripting)
CSRF (Cross-Site Request Forgery)
NoSQL Injection
Brute Force Attacks
Man-in-the-Middle Attacks

Security Measures:
Use HTTPS
Validate and sanitize input
Implement rate limiting
Use security headers (Helmet)
Hash passwords (bcrypt)
Prevent parameter pollution
Use CORS properly
Keep dependencies updated

Code Example

javascript
// ========== Helmet (Security Headers) ==========

// Install: npm install helmet

const helmet = require('helmet');

[Link](helmet());

// Or customize
[Link](helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", 'data:', 'https:']
}
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));

// ========== CORS ==========

const cors = require('cors');

// Allow all origins (not recommended for production)


[Link](cors());

// Configure CORS
const corsOptions = {
origin: ['[Link] '[Link]
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400 // 24 hours
};

[Link](cors(corsOptions));

// ========== Rate Limiting ==========

const rateLimit = require('express-rate-limit');


const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP',
standardHeaders: true,
legacyHeaders: false
});

[Link]('/api/', limiter);

// Stricter limit for auth routes


const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: 'Too many login attempts'
});

[Link]('/api/auth/', authLimiter);

// ========== Input Validation and Sanitization ==========

const { body, validationResult } = require('express-validator');


const mongoSanitize = require('express-mongo-sanitize');

// Sanitize data
[Link](mongoSanitize());

// Validate input
[Link]('/users',
body('email').isEmail().normalizeEmail(),
body('password').isLength({ min: 6 }).trim().escape(),
body('name').trim().escape(),
(req, res) => {
const errors = validationResult(req);

if (![Link]()) {
return [Link](400).json({ errors: [Link]() });
}

// Process request
}
);

// ========== Prevent Parameter Pollution ==========

const hpp = require('hpp');


[Link](hpp({
whitelist: ['sort', 'fields'] // Allow these params to be arrays
}));

// ========== XSS Protection ==========

const xss = require('xss-clean');

[Link](xss());

// ========== CSRF Protection ==========

const csrf = require('csurf');


const cookieParser = require('cookie-parser');

[Link](cookieParser());

const csrfProtection = csrf({ cookie: true });

[Link]('/form', csrfProtection, (req, res) => {


[Link]('form', { csrfToken: [Link]() });
});

[Link]('/form', csrfProtection, (req, res) => {


[Link]('Form submitted');
});

// ========== Password Security ==========

const bcrypt = require('bcryptjs');

// Hash password
const hashPassword = async (password) => {
const salt = await [Link](12);
return await [Link](password, salt);
};

// Compare password
const comparePassword = async (password, hashedPassword) => {
return await [Link](password, hashedPassword);
};

// ========== Secure Session Configuration ==========

[Link](session({
secret: [Link].SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: [Link].NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 1000 * 60 * 60 * 24 // 1 day
}
}));

// ========== Environment Variables ==========

require('dotenv').config();

// Never commit .env file


const config = {
port: [Link] || 3000,
dbUrl: [Link].DATABASE_URL,
jwtSecret: [Link].JWT_SECRET
};

// ========== SQL Injection Prevention ==========

// Use parameterized queries


const query = 'SELECT * FROM users WHERE email = ?';
[Link](query, [email]);

// Or use ORM (Sequelize, TypeORM)

// ========== Security Checklist ==========

/*
✅ Use HTTPS in production
✅ Validate all user input
✅ Sanitize data to prevent injection
✅ Hash passwords with bcrypt
✅ Use helmet for security headers
✅ Implement rate limiting
✅ Use CORS properly
✅ Keep dependencies updated
✅ Use environment variables for secrets
✅ Implement proper error handling
✅ Log security events
✅ Use secure session configuration
✅ Implement CSRF protection for forms
✅ Prevent parameter pollution
✅ Use Content Security Policy
✅ Implement proper authentication
✅ Use role-based authorization
*/

Mistakes to Avoid
❌ Mistake 1: Exposing sensitive information

javascript

// Bad: Revealing error details


[Link]((err, req, res, next) => {
[Link]({ error: [Link] });
});

✅ Correct: Generic error messages in production

javascript

// Good: Safe error handling


[Link]((err, req, res, next) => {
if ([Link].NODE_ENV === 'production') {
[Link](500).json({ error: 'Something went wrong' });
} else {
[Link](500).json({ error: [Link], stack: [Link] });
}
});

19. Testing
Theory
Testing Types:
Unit Tests: Test individual functions
Integration Tests: Test multiple components
End-to-End Tests: Test entire application
API Tests: Test API endpoints

Testing Tools:
Jest: Testing framework
Mocha: Test framework
Chai: Assertion library
Supertest: HTTP assertions
Sinon: Mocking library
Test Structure:
Arrange: Set up test data
Act: Execute function
Assert: Verify results

Code Example

javascript
// ========== Jest Setup ==========

// Install: npm install --save-dev jest supertest

// [Link]
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}

// [Link]
[Link] = {
testEnvironment: 'node',
coveragePathIgnorePatterns: ['/node_modules/'],
testMatch: ['**/__tests__/**/*.js', '**/?(*.)+(spec|test).js']
};

// ========== Unit Tests ==========

// utils/[Link]
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;

[Link] = { add, subtract };

// __tests__/[Link]
const { add, subtract } = require('../utils/math');

describe('Math utilities', () => {


describe('add', () => {
it('should add two numbers correctly', () => {
expect(add(2, 3)).toBe(5);
});

it('should handle negative numbers', () => {


expect(add(-2, 3)).toBe(1);
});
});

describe('subtract', () => {
it('should subtract two numbers correctly', () => {
expect(subtract(5, 3)).toBe(2);
});
});
});

// ========== API Tests with Supertest ==========

// [Link]
const express = require('express');
const app = express();

[Link]([Link]());

[Link]('/users', (req, res) => {


[Link]({ users: [] });
});

[Link]('/users', (req, res) => {


[Link](201).json({ user: [Link] });
});

[Link] = app;

// __tests__/[Link]
const request = require('supertest');
const app = require('../app');

describe('Users API', () => {


describe('GET /users', () => {
it('should return empty array', async () => {
const response = await request(app)
.get('/users')
.expect(200);

expect([Link]).toEqual([]);
});
});

describe('POST /users', () => {


it('should create user', async () => {
const user = { name: 'John', email: 'john@[Link]' };

const response = await request(app)


.post('/users')
.send(user)
.expect(201);

expect([Link]).toMatchObject(user);
});
it('should return 400 for invalid data', async () => {
await request(app)
.post('/users')
.send({})
.expect(400);
});
});
});

// ========== Mocking with Jest ==========

// services/[Link]
const getUser = async (id) => {
const user = await [Link](id);
return user;
};

[Link] = { getUser };

// __tests__/[Link]
const { getUser } = require('../services/userService');
const User = require('../models/User');

[Link]('../models/User');

describe('User Service', () => {


it('should get user by id', async () => {
const mockUser = { _id: '123', name: 'John' };
[Link](mockUser);

const user = await getUser('123');

expect([Link]).toHaveBeenCalledWith('123');
expect(user).toEqual(mockUser);
});
});

// ========== Test Coverage ==========

// npm run test:coverage

// Will generate coverage report in coverage/

// ========== Integration Tests ==========

const mongoose = require('mongoose');


describe('User Integration Tests', () => {
beforeAll(async () => {
await [Link]([Link].TEST_DATABASE_URL);
});

afterAll(async () => {
await [Link]();
});

beforeEach(async () => {
await [Link]({});
});

it('should create and retrieve user', async () => {


const userData = { name: 'John', email: 'john@[Link]' };

const response = await request(app)


.post('/users')
.send(userData)
.expect(201);

const userId = [Link]._id;

const getResponse = await request(app)


.get(`/users/${userId}`)
.expect(200);

expect([Link]).toBe([Link]);
});
});

Mistakes to Avoid
❌ Mistake 1: Not testing error cases

javascript

// Bad: Only testing success


it('should create user', async () => {
const response = await request(app)
.post('/users')
.send({ name: 'John' })
.expect(201);
});

✅ Correct: Test both success and error cases


javascript

// Good: Test success and errors


it('should create user with valid data', async () => {
await request(app)
.post('/users')
.send({ name: 'John', email: 'john@[Link]' })
.expect(201);
});

it('should return 400 for invalid data', async () => {


await request(app)
.post('/users')
.send({ name: 'John' }) // Missing email
.expect(400);
});

20. Performance Optimization


Theory
Performance Bottlenecks:
Database queries
Large response payloads
Synchronous operations
Memory leaks
Inefficient algorithms

Optimization Techniques:
Database indexing
Caching (Redis)
Compression
Load balancing
Connection pooling
Code splitting
Lazy loading

Code Example

javascript
// ========== Compression ==========

const compression = require('compression');

[Link](compression());

// ========== Caching with Redis ==========

const redis = require('redis');


const client = [Link]();

[Link]('error', (err) => [Link]('Redis error:', err));

// Cache middleware
const cache = (duration) => {
return async (req, res, next) => {
const key = `cache:${[Link]}`;

const cachedData = await [Link](key);

if (cachedData) {
return [Link]([Link](cachedData));
}

// Store original json function


const originalJson = [Link](res);

// Override json function


[Link] = (data) => {
[Link](key, duration, [Link](data));
return originalJson(data);
};

next();
};
};

// Use cache
[Link]('/users', cache(60), async (req, res) => {
const users = await [Link]();
[Link]({ users });
});

// ========== Database Indexing ==========

// Create index
[Link]({ email: 1 });
[Link]({ name: 1, createdAt: -1 });

// ========== Connection Pooling ==========

[Link]([Link].DATABASE_URL, {
maxPoolSize: 10,
minPoolSize: 5
});

// ========== Pagination ==========

[Link]('/users', async (req, res) => {


const page = parseInt([Link]) || 1;
const limit = parseInt([Link]) || 10;

const users = await [Link]()


.limit(limit)
.skip((page - 1) * limit)
.lean(); // Returns plain JS objects (faster)

[Link]({ users });


});

// ========== Field Selection ==========

[Link]('/users', async (req, res) => {


const users = await [Link]()
.select('name email -_id');

[Link]({ users });


});

// ========== Clustering ==========

const cluster = require('cluster');


const os = require('os');

if ([Link]) {
const numCPUs = [Link]().length;

for (let i = 0; i < numCPUs; i++) {


[Link]();
}

[Link]('exit', (worker) => {


[Link](`Worker ${[Link]} died`);
[Link]();
});
} else {
[Link](3000);
}

// ========== Monitoring ==========

const morgan = require('morgan');

[Link](morgan('combined'));

Mistakes to Avoid
❌ Mistake 1: Loading entire collections

javascript

// Bad: Loads all users into memory


const users = await [Link]();

✅ Correct: Use pagination and limits

javascript

// Good: Paginated results


const users = await [Link]()
.limit(10)
.skip(0);

21. Deployment
Theory
Deployment Platforms:
Heroku
AWS (EC2, Elastic Beanstalk, Lambda)
DigitalOcean
Vercel
Railway
Render

Best Practices:
Use environment variables
Enable logging
Set up monitoring
Use process managers (PM2)
Implement CI/CD
Use HTTPS
Database backups

Code Example

javascript
// ========== Production Server Setup ==========

// [Link]
const app = require('./app');

const PORT = [Link] || 3000;

const server = [Link](PORT, () => {


[Link](`Server running on port ${PORT}`);
});

// Graceful shutdown
[Link]('SIGTERM', () => {
[Link]('SIGTERM received, closing server...');
[Link](() => {
[Link]('Server closed');
[Link]();
[Link](0);
});
});

// ========== PM2 Configuration ==========

// [Link]
[Link] = {
apps: [{
name: 'api',
script: './[Link]',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};

// Start with PM2


// pm2 start [Link] --env production

// ========== Docker ==========

// Dockerfile
/*
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm ci --only=production

COPY . .

EXPOSE 3000

CMD ["node", "[Link]"]


*/

// [Link]
/*
version: '3.8'

services:
api:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=mongodb://mongo:27017/myapp
depends_on:
- mongo

mongo:
image: mongo:latest
volumes:
- mongo-data:/data/db

volumes:
mongo-data:
*/

// ========== Heroku Deployment ==========

// Procfile
// web: node [Link]

// [Link]
{
"engines": {
"node": "18.x",
"npm": "9.x"
}
}

// Deploy
// heroku create myapp
// git push heroku main

// ========== Environment Configuration ==========

// config/[Link]
[Link] = {
development: {
port: 3000,
dbUrl: 'mongodb://localhost:27017/myapp-dev'
},
production: {
port: [Link],
dbUrl: [Link].DATABASE_URL
}
};

const config = require('./config')[[Link].NODE_ENV || 'development'];

Summary and Best Practices


[Link] Best Practices
1. Always use async operations - Avoid blocking the event loop
2. Handle errors properly - Use try-catch and error middleware
3. Use environment variables - Never hardcode secrets
4. Implement logging - Use Winston or Bunyan
5. Keep dependencies updated - Run npm audit regularly
6. Use linting and formatting - ESLint and Prettier
7. Write tests - Aim for good code coverage
8. Monitor performance - Use APM tools
9. Implement security measures - Helmet, CORS, rate limiting
10. Document your API - Use Swagger or similar
[Link] Best Practices
1. Use middleware correctly - Order matters
2. Structure your application - Use routers and controllers
3. Validate input - Use express-validator
4. Use compression - Reduce payload size
5. Implement caching - Redis for frequently accessed data
6. Use proper status codes - RESTful conventions
7. Version your API - /api/v1, /api/v2
8. Implement pagination - Don't return all records
9. Use HTTPS in production - Encrypt data in transit
10. Set up proper error handling - Centralized error middleware

Additional Resources
[Link] Documentation
[Link] Guide
MongoDB University
PostgreSQL Tutorial
[Link]
MDN Web Docs

End of Complete [Link] and [Link] Notes

You might also like