Nodejs Expressjs Complete Notes - MD
Nodejs Expressjs Complete Notes - MD
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
Code Example
javascript
// Basic [Link] script
[Link]('Hello from [Link]!');
// Environment information
[Link](`Platform: ${[Link]}`);
[Link](`Architecture: ${[Link]}`);
// Process information
[Link](`Process ID: ${[Link]}`);
[Link](`Current directory: ${[Link]()}`);
// Environment variables
[Link](`NODE_ENV: ${[Link].NODE_ENV}`);
Mistakes to Avoid
❌ Mistake 1: Thinking [Link] is multi-threaded
javascript
javascript
javascript
// Bad: Blocks the entire event loop
const fs = require('fs');
const data = [Link]('[Link]', 'utf8');
javascript
const fs = require('fs').promises;
const data = await [Link]('[Link]', 'utf8');
javascript
javascript
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
// Buffer
const buf = [Link]('Hello World');
[Link](buf); // <Buffer 48 65 6c 6c 6f 20 57 6f 72 6c 64>
[Link]([Link]()); // Hello World
// Timers
setTimeout(() => [Link]('Timeout'), 1000);
setInterval(() => [Link]('Interval'), 2000);
setImmediate(() => [Link]('Immediate'));
Mistakes to Avoid
❌ Mistake 1: Polluting the global namespace
javascript
// [Link]
[Link] = {
myVariable: 'value'
};
// [Link]
const config = require('./config');
javascript
javascript
javascript
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 ==========
function subtract(a, b) {
return a - b;
}
// Destructuring import
const { add, subtract } = require('./math');
[Link](add(10, 5)); // 15
// 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
// [Link]
const config = require('./config');
[Link]([Link]); // 'modified' - same instance!
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]
javascript
javascript
// [Link]
const b = require('./b');
[Link] = { name: 'A', b };
// [Link]
const a = require('./a'); // a is incomplete here!
[Link] = { name: 'B', a };
javascript
// [Link]
[Link] = { shared: 'data' };
// [Link]
const shared = require('./shared');
// [Link]
const shared = require('./shared');
javascript
// Can't use require in ES modules
// Can't use import in CommonJS without dynamic import()
javascript
// CommonJS
const module = require('module');
// ES Modules
import module from 'module';
[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 ==========
# 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
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
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
bash
bash
bash
{
"dependencies": {
"express": "*", // Very bad
"mongoose": "latest" // Bad
}
}
json
{
"dependencies": {
"express": "4.18.2", // Exact version
"mongoose": "^7.0.0" // Allow patch and minor updates
}
}
bash
bash
npm audit
npm audit fix
npm audit fix --force # For breaking changes (careful!)
bash
bash
# Use only npm
npm install express
npm install mongoose
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');
});
// 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();
// Read directory
const files = await [Link]('.');
[Link]('Files:', files);
// 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);
}
}
[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);
}
}
}
// 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'
// }
// Usage
if (await fileExists('[Link]')) {
[Link]('File exists');
}
// Usage
const config = await readJSON('[Link]');
await writeJSON('[Link]', { name: 'John', age: 30 });
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
javascript
// Good: Non-blocking
const data = await [Link]('[Link]', 'utf8');
// Or with callbacks
[Link]('[Link]', 'utf8', (err, data) => {
if (err) throw err;
[Link](data);
});
javascript
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);
}
}
javascript
javascript
javascript
javascript
javascript
// Bad: Fails if parent doesn't exist
await [Link]('./a/b/c');
javascript
javascript
javascript
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 ==========
// Usage
readFileCallback('[Link]', (err, data) => {
if (err) {
[Link]('Error:', err);
return;
}
[Link]('Data:', data);
});
// 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](promises)
.then(results => {
[Link]('All files:', results);
})
.catch(error => {
[Link]('One or more failed:', error);
});
} catch (error) {
[Link]('Error reading files:', error);
throw error;
} finally {
[Link]('Cleanup');
}
}
} catch (error) {
[Link]('Error:', error);
}
}
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';
}
// Custom promisify
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
};
}
[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)
// Parallel processing
const results = await [Link](
[Link](item => processItem(item))
);
[Link](results);
}
} catch (error) {
[Link]('Error fetching user data:', error);
throw error;
}
}
Mistakes to Avoid
❌ Mistake 1: Not handling Promise rejections
javascript
javascript
// Or use try-catch
async function main() {
try {
await getData();
} catch (error) {
[Link](error);
}
}
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
javascript
javascript
javascript
javascript
// Bad: Doesn't wait for inner promise
doSomething()
.then(() => {
doSomethingElse(); // Missing return!
})
.then(() => {
// This runs before doSomethingElse completes
});
javascript
javascript
javascript
javascript
// Bad: One failure stops everything
const results = await [Link]([
operation1(),
operation2(), // If this fails, we lose results from operation1 and 3
operation3()
]);
javascript
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...
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 ==========
// Write to buffer
[Link]('Hi');
[Link]([Link]()); // 'Hi\x00\x00\x00\x00\x00\x00\x00\x00'
// 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
// Event-based consumption
[Link]('data', (chunk) => {
[Link]('Received chunk:', [Link], 'bytes');
});
[Link]('end', () => {
[Link]('Finished reading file');
});
setTimeout(() => {
[Link]('Resuming...');
[Link]();
}, 1000);
});
// Write data
[Link]('First line\n');
[Link]('Second line\n');
[Link]('Final line\n'); // Write and close
// Events
[Link]('finish', () => {
[Link]('Writing finished');
});
[Link]('[Link]')
.pipe(createGzip())
.pipe([Link]('[Link]'))
.on('finish', () => [Link]('File compressed'));
_read() {
if ([Link] <= [Link]) {
[Link]([Link]() + '\n');
[Link]++;
} else {
[Link](null); // End stream
}
}
}
_read() {
const chunk = [Link]();
[Link](chunk || null);
}
readStream
.pipe(writeStream)
.on('finish', resolve)
.on('error', reject);
});
}
const rl = [Link]({
input: readStream,
crlfDelay: Infinity
});
return count;
}
return results;
}
// 4. Compress file
const { createGzip } = require('zlib');
// 5. Decompress file
const { createGunzip } = require('zlib');
[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
javascript
// Good: Process in chunks
const readStream = [Link]('[Link]');
[Link]('data', (chunk) => {
processChunk(chunk);
});
javascript
javascript
javascript
javascript
javascript
javascript
// Good: Zero-initialized
const buf1 = [Link](1024);
javascript
javascript
// Good: Close stream
[Link]('data');
[Link]();
javascript
javascript
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!
[Link]('data', () => {
[Link]('First listener');
});
[Link]('data', () => {
[Link]('Second listener');
});
[Link]('data');
// First listener
// Second listener
function onData() {
[Link]('Data received');
}
[Link]('data', onData);
[Link]('data'); // Data received
[Link]('data', onData);
// or: [Link]('data', onData);
[Link]('data'); // Nothing
login() {
[Link](`${[Link]} is logging in...`);
[Link]('login', [Link]);
}
logout() {
[Link](`${[Link]} is logging out...`);
[Link]('logout', [Link]);
}
}
[Link]();
// Alice is logging in...
// Welcome, Alice!
addJob(job) {
[Link](job);
[Link]('jobAdded', job);
if (![Link]) {
[Link]();
}
}
async processJobs() {
[Link] = true;
try {
const result = await [Link]();
[Link]('jobCompleted', job, result);
} catch (error) {
[Link]('jobFailed', job, error);
}
}
[Link] = false;
[Link]('queueEmpty');
}
}
Mistakes to Avoid
❌ Mistake 1: Not handling 'error' events
javascript
javascript
javascript
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
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');
[Link](3000, () => {
[Link]('Server running on [Link]
});
// GET request
[Link]('[Link] (res) => {
let data = '';
[Link]('end', () => {
[Link]('Response:', data);
});
}).on('error', (error) => {
[Link]('Error:', error);
});
Mistakes to Avoid
❌ Mistake 1: Not calling [Link]()
javascript
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
// Simple route
[Link]('/', (req, res) => {
[Link]('Hello World!');
});
// Start server
[Link](3000, () => {
[Link]('Server running on [Link]
});
// Middleware
[Link]([Link]());
[Link]([Link]('public'));
// Routes
[Link]('/', (req, res) => {
[Link]('Home Page');
});
// 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
javascript
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();
});
// 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]({
query: q,
page: parseInt(page) || 1,
limit: parseInt(limit) || 10
});
});
// 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();
};
// Router-level middleware
[Link]((req, res, next) => {
[Link]('Router middleware');
next();
});
// Define routes
[Link]('/', (req, res) => {
[Link]({ message: 'User list' });
});
// Mount router
[Link]('/api/users', router);
// routes/[Link]
const express = require('express');
const router = [Link]();
[Link] = router;
// [Link]
const userRoutes = require('./routes/users');
[Link]('/api/users', userRoutes);
// Wildcards
[Link]('/files/*', (req, res) => {
[Link]('File route');
});
// Regular expressions
[Link](/.*fly$/, (req, res) => {
[Link]('butterfly, dragonfly, etc.');
});
[Link]('/book')
.get((req, res) => {
[Link]('Get a book');
})
.post((req, res) => {
[Link]('Add a book');
})
.put((req, res) => {
[Link]('Update a book');
});
[Link]('/users', usersRouter);
[Link]('/posts', postsRouter);
[Link]('/api', apiRouter);
// Routes: /api/users, /api/posts
// routes/api/[Link]
const express = require('express');
const router = [Link]();
[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
// Or query string
[Link]('/users', (req, res) => {
const id = [Link];
});
javascript
javascript
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
Error-Handling Middleware:
javascript
Code Example
javascript
// ========== Application-Level Middleware ==========
const express = require('express');
const app = express();
// Cookie Parser
const cookieParser = require('cookie-parser');
[Link](cookieParser());
// Compression
const compression = require('compression');
[Link](compression());
// 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];
// Router middleware
[Link]((req, res, next) => {
[Link]('Router middleware');
next();
});
[Link]('/api', router);
[Link](conditionalMiddleware);
[Link]('finish', () => {
const duration = [Link]() - [Link];
[Link](`${[Link]} ${[Link]} - ${duration}ms`);
});
next();
});
// 2. Request ID middleware
const { v4: uuidv4 } = require('uuid');
[Link]('/api/', limiter);
if (!name || !email) {
return [Link](400).json({
error: 'Name and email are required'
});
}
if () {
return [Link](400).json({
error: 'Invalid email format'
});
}
next();
};
[Link]('/users', validateUser, (req, res) => {
[Link](201).json({ message: 'User created' });
});
[Link] = function(data) {
const wrappedData = {
success: true,
data: data,
timestamp: new Date().toISOString()
};
next();
});
Mistakes to Avoid
❌ Mistake 1: Not calling next()
javascript
javascript
javascript
// Bad: Routes before body parser
[Link]('/user', (req, res) => {
[Link]([Link]); // undefined
});
[Link]([Link]());
javascript
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 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]());
// Headers
[Link]([Link]);
const userAgent = [Link]('User-Agent');
const contentType = [Link]('Content-Type');
// Method
[Link]([Link]); // GET
// IP address
[Link]([Link]); // Client IP
[Link]([Link]); // Array of IPs (if behind proxy)
// Hostname
[Link]([Link]); // [Link]
[Link]([Link]); // ['api'] for [Link]
[Link]('Uploaded');
});
// Send text
[Link]('/text', (req, res) => {
[Link]('Plain text response');
});
// Send JSON
[Link]('/json', (req, res) => {
[Link]({
user: 'John',
age: 30,
active: true
});
});
// Chain methods
[Link]('/chain', (req, res) => {
res
.status(200)
.set('Content-Type', 'application/json')
.json({ message: 'Chained response' });
});
// Send file
const path = require('path');
// 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');
});
// Get header
[Link]('/check-header', (req, res) => {
const auth = [Link]('Authorization');
[Link]({ auth });
});
// 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');
});
// Success
[Link]('/success', (req, res) => {
[Link](200).json({ message: 'OK' });
});
// Client Errors
[Link]('/bad-request', (req, res) => {
[Link](400).json({ error: 'Bad Request' });
});
// Server Errors
[Link]('/server-error', (req, res) => {
[Link](500).json({ error: 'Internal Server Error' });
});
setTimeout(() => {
[Link]('Chunk 2\n');
}, 1000);
setTimeout(() => {
[Link]('Final chunk\n');
}, 2000);
});
Mistakes to Avoid
❌ Mistake 1: Sending response multiple times
javascript
javascript
javascript
// Bad: Might send response twice
[Link]('/data', (req, res) => {
if (error) {
[Link](500).json({ error });
}
[Link]({ data }); // Sent even if error
});
javascript
Code Example
javascript
// ========== Setting Up Template Engine ==========
const express = require('express');
const app = express();
// views/[Link]
/*
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1>Welcome <%= name %>!</h1>
<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' }
]
});
});
// 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') %>
*/
// 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' }
]
});
});
[Link]('hbs', engine({
extname: '.hbs',
defaultLayout: 'main',
layoutsDir: [Link](__dirname, 'views', 'layouts'),
partialsDir: [Link](__dirname, 'views', 'partials')
}));
// 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' }
]
});
});
[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;
}
}
}));
javascript
javascript
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();
[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));
});
[Link](statusCode).json({
status: 'error',
statusCode,
message,
...([Link].NODE_ENV === 'development' && { stack: [Link] })
});
});
[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]()
});
}
// 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';
[Link] = errorHandler;
Mistakes to Avoid
❌ Mistake 1: Not passing async errors to next()
javascript
javascript
// Good: Proper error handling
[Link]('/users', async (req, res, next) => {
try {
const users = await [Link]();
[Link](users);
} catch (error) {
next(error);
}
});
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 ==========
// 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);
// 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' });
}
// 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);
}
});
if (minAge || maxAge) {
[Link] = {};
if (minAge) [Link].$gte = parseInt(minAge);
if (maxAge) [Link].$lte = parseInt(maxAge);
}
if (role) {
[Link] = role;
}
// Pre-save middleware
[Link]('save', async function(next) {
// Hash password before saving
if () return next();
// Instance method
[Link] = async function(candidatePassword) {
const bcrypt = require('bcryptjs');
return await [Link](candidatePassword, [Link]);
};
// Static method
[Link] = function(email) {
return [Link]({ email });
};
// 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));
Mistakes to Avoid
❌ Mistake 1: Not handling validation errors
javascript
// Bad: No validation
const user = await [Link]([Link]);
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...
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
Code Example
javascript
// ========== Session-Based Authentication ==========
[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];
[Link] = user._id;
[Link] = [Link];
// 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 });
});
// Sign up
[Link]('/signup', async (req, res, next) => {
try {
const { name, email, password } = [Link];
// 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];
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);
}
});
// Verify token
const decoded = [Link](token, JWT_SECRET);
if (!user) {
return [Link](401).json({ error: 'User not found' });
}
// Protected route
[Link]('/profile', authenticateJWT, (req, res) => {
[Link]({ user: [Link] });
});
if () {
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);
}
}
);
if (!refreshToken) {
return [Link](401).json({ error: 'No refresh token' });
}
if (!user) {
return [Link](401).json({ error: 'User not found' });
}
if (!user) {
return [Link](404).json({ error: 'User not found' });
}
// Reset password
[Link]('/reset-password/:token', async (req, res, next) => {
try {
const hashedToken = crypto
.createHash('sha256')
.update([Link])
.digest('hex');
if (!user) {
return [Link](400).json({ error: 'Invalid or expired token' });
}
[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
javascript
javascript
// Bad: No verification
const token = [Link];
const user = [Link](atob([Link]('.')[1]));
javascript
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 ==========
[Link]({
status: 'success',
results: [Link],
total,
page: parseInt(page),
pages: [Link](total / parseInt(limit)),
data: { users }
});
} catch (error) {
next(error);
}
});
if (!user) {
return [Link](404).json({
status: 'fail',
message: 'User not found'
});
}
[Link]({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});
[Link](201).json({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});
if (!user) {
return [Link](404).json({
status: 'fail',
message: 'User not found'
});
}
[Link]({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});
if (!user) {
return [Link](404).json({
status: 'fail',
message: 'User not found'
});
}
[Link]({
status: 'success',
data: { user }
});
} catch (error) {
next(error);
}
});
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);
}
});
// [Link]
[Link]('/api/v1/users', require('./routes/v1/users'));
[Link]('/api/v2/users', require('./routes/v2/users'));
if (minAge || maxAge) {
[Link] = {};
if (minAge) [Link].$gte = parseInt(minAge);
if (maxAge) [Link].$lte = parseInt(maxAge);
}
[Link]({
status: 'success',
results: [Link],
pagination: {
page,
limit,
totalPages: [Link](total / limit),
total
},
data: { users }
});
} catch (error) {
next(error);
}
});
if (fields) {
const selectedFields = [Link](',').join(' ');
query = [Link](selectedFields);
}
[Link]('/api/', apiLimiter);
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
javascript
javascript
javascript
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) ==========
[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
}
}));
// 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));
[Link]('/api/', limiter);
[Link]('/api/auth/', authLimiter);
// 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
}
);
[Link](xss());
[Link](cookieParser());
// 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);
};
[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
}
}));
require('dotenv').config();
/*
✅ 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
javascript
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 ==========
// [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']
};
// utils/[Link]
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;
// __tests__/[Link]
const { add, subtract } = require('../utils/math');
describe('subtract', () => {
it('should subtract two numbers correctly', () => {
expect(subtract(5, 3)).toBe(2);
});
});
});
// [Link]
const express = require('express');
const app = express();
[Link]([Link]());
[Link] = app;
// __tests__/[Link]
const request = require('supertest');
const app = require('../app');
expect([Link]).toEqual([]);
});
});
expect([Link]).toMatchObject(user);
});
it('should return 400 for invalid data', async () => {
await request(app)
.post('/users')
.send({})
.expect(400);
});
});
});
// 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');
expect([Link]).toHaveBeenCalledWith('123');
expect(user).toEqual(mockUser);
});
});
afterAll(async () => {
await [Link]();
});
beforeEach(async () => {
await [Link]({});
});
expect([Link]).toBe([Link]);
});
});
Mistakes to Avoid
❌ Mistake 1: Not testing error cases
javascript
Optimization Techniques:
Database indexing
Caching (Redis)
Compression
Load balancing
Connection pooling
Code splitting
Lazy loading
Code Example
javascript
// ========== Compression ==========
[Link](compression());
// Cache middleware
const cache = (duration) => {
return async (req, res, next) => {
const key = `cache:${[Link]}`;
if (cachedData) {
return [Link]([Link](cachedData));
}
next();
};
};
// Use cache
[Link]('/users', cache(60), async (req, res) => {
const users = await [Link]();
[Link]({ users });
});
// Create index
[Link]({ email: 1 });
[Link]({ name: 1, createdAt: -1 });
[Link]([Link].DATABASE_URL, {
maxPoolSize: 10,
minPoolSize: 5
});
if ([Link]) {
const numCPUs = [Link]().length;
[Link](morgan('combined'));
Mistakes to Avoid
❌ Mistake 1: Loading entire collections
javascript
javascript
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');
// Graceful shutdown
[Link]('SIGTERM', () => {
[Link]('SIGTERM received, closing server...');
[Link](() => {
[Link]('Server closed');
[Link]();
[Link](0);
});
});
// [Link]
[Link] = {
apps: [{
name: 'api',
script: './[Link]',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};
// Dockerfile
/*
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
COPY . .
EXPOSE 3000
// [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:
*/
// Procfile
// web: node [Link]
// [Link]
{
"engines": {
"node": "18.x",
"npm": "9.x"
}
}
// Deploy
// heroku create myapp
// git push heroku main
// config/[Link]
[Link] = {
development: {
port: 3000,
dbUrl: 'mongodb://localhost:27017/myapp-dev'
},
production: {
port: [Link],
dbUrl: [Link].DATABASE_URL
}
};
Additional Resources
[Link] Documentation
[Link] Guide
MongoDB University
PostgreSQL Tutorial
[Link]
MDN Web Docs