Week 4
Node.js ♻️
o What is Node.js ?
Not a language and not a framework it is a Run time environment for
JS
You can run JS outside of the browser - (server)
JavaScript can talk to native machine because of c++
You can create webservers in JavaScript Language
o Why we use Node.js ?
Scalability:
Node.js is suitable for building scalable applications that can handle
many concurrent users and connections, making it great for real-time
applications like chat systems and live updates.
Event driven
It allows the application to respond to events ( HTTP requests or file
I/O ) by attaching callback function to event listeners, making it well
suited for asynchronous operations.
const express = require('express');
const app = express();
// Event listener for GET request to '/hello'
app.get('/hello', (req, res) => { // This is the
callback function
console.log('Received a GET request at /hello');
// Respond to the client
res.send('Hello, Express World!'); // This sends a
response using the `res` object
});
// Start the server to listen for requests on port 3000
app.listen(3000, () => {
console.log('Server is running on
<http://localhost:3000>');
});
Speed and Efficiency:
Built on the V8 engine, Node.js executes JavaScript code very quickly.
Non-blocking i/o model
Node.js uses a non-blocking event loop, which allows it to handle
multiple tasks simultaneously without waiting for one task to finish
before starting the next.
NPM (Node Package Manager):
Node.js comes with NPM, a massive repository of over a million open-
source libraries, which helps developers quickly add functionality to
their projects.
Full-Stack Development:
JavaScript is used on both the client and server sides, Node.js enables
full-stack development with a single language, simplifying workflows
for developers
o Where We Use Node.js ?
Web Servers: Hosting websites and APId to respond quickly to user
requests.
Real time Aplications: Building apps like chat applicationd, online
games, and collaboration tools that need to update insantly
Data Streaming: Handiling streaming data for services video
platforms, where data is processed and sent out continuously.
APIs and Microservises: Building backed services that connect
different parts of a system, allowing them to work together smoothly
o Advantages of NODE ?
Fast Execution
Built on the V8 engine, Node.js executes JavaScript code very quickly.
Scalability
Node.js is suitable for building scalable applications that can handle
many concurrent users and connections, making it great for real-time
applications like chat systems and live updates.
Cross-Platform Development
Node.js can be used to build cross-platform apps for various operating
systems, including Windows, Linux, and macOS.
Asynchronous and Non-blocking I/O
Node.js can handle multiple requests simultaneously without waiting
for one to finish before starting the next. This improves performance,
especially for I/O-heavy tasks like database queries and file handling.
Single Programming Language
With Node.js, developers can use JavaScript on both the frontend and
backend, simplifying the development process for full-stack
developers.
Large Community and NPM
Node.js has a huge developer community and access to the Node
Package Manager (NPM), which hosts thousands of reusable
packages, modules, and libraries.
o Disadvantages of NODE ?
Single-Threaded Nature: Limits performance for CPU-intensive
tasks.
Callback Hell: Can lead to complex and difficult-to-maintain nested
code.
Performance Bottlenecks: Inefficient for heavy computation or
processing tasks.
Error Handling Challenges: Can be complicated in asynchronous
code.
Security Concerns: Vulnerable to common web security issues if not
properly managed.
o Features of NODE ?
Event-Driven: Event-driven means the system reacts to events (like clicks or
requests) as they happen. In Node.js, this allows it to handle multiple actions
efficiently without waiting for each task to finish before starting the next one.
Non-blocking I/O:Node.js employs non-blocking I/O, meaning it can process
multiple requests at the same time without waiting for the previous ones to
finish.
NPM (Node Package Manager):Node.js comes with NPM, a massive
repository of over a million open-source libraries, which helps developers
quickly add functionality to their projects.
Cross-platform Compatibility: You can develop applications that run on
different operating systems
Full-Stack Development: JavaScript is used on both the client and server
sides, Node.js enables full-stack development with a single language,
simplifying workflows for developers
o Node Concurrency
Node.js uses an event-driven, non-blocking I/O model to handle multiple
requests concurrently without creating multiple threads for each request. This
is achieved through the event loop.
o Reactor Pattern
The Reactor Pattern is a design pattern used in Node.js to handle multiple I/O
operations efficiently. It delegates I/O tasks to an event loop and, once these
tasks are completed, invokes the appropriate event handlers asynchronously.
How it Works:
1. Event Loop:
The core of the Reactor Pattern is the event loop, which constantly
listens for I/O events (e.g., file read/write, network requests).
2. Event Demultiplexer:
The event loop uses an event demultiplexer to monitor multiple file
descriptors or network sockets simultaneously.
3. Callbacks:
When an I/O operation completes, the associated callback function is
executed.
4. Non-blocking Behavior:
Other operations continue to execute without waiting for the I/O task
to complete, ensuring non-blocking behavior.
Why It's Used in Node.js:
Efficiency: Handles a large number of I/O-bound tasks without
creating additional threads.
Scalability: Suitable for applications with high concurrency needs, like
web servers or APIs.
Single-threaded Design: Works seamlessly with Node.js's single-
threaded, event-driven architecture.
o Runtime Environment VS Framework
Runtime Environment
Focuses on providing the necessary infrastructure for code execution,
including services like memory management and I/O operations
Framework
Focuses on simplifying the development process by offering a
structured set of tools, libraries, and best practice.
o Best Types of Projects for node ?
REST API & Microservices
Real time services (Chat, live updates)
CURD Apps - Blogs, shopping carts, social networks
Tools & Utilities
Anything that is not CPU intensive
Express.js ㊙️
o What is Express ?
Express is a minimal and flexible web application framework for Node.js.
o Why we use Express ?
Easy Routing: Simplifies the process of defining routes for handling
requests.
Middleware Support: Allows easy integration of middleware for
request processing and handling.
Fast Development: Accelerates the development of web applications
and APIs.
Flexible: Can be customized for different needs, making it suitable for
various projects.
Large Ecosystem: Offers a wide range of third-party middleware and
libraries for added functionality.
RESTful API Support: Facilitates the creation of RESTful APIs with
simple syntax.
o Features of Express ?
Minimalist Framework:
Lightweight and flexible, allowing developers to structure
applications according to their preferences.
Middleware Support:
Enables the integration of middleware functions to handle
requests, responses, and errors efficiently.
Robust Routing:
Provides a powerful routing system to define routes for
different HTTP methods and URLs.
Static File Serving:
Easily serve static files (like images, CSS, and JavaScript)
through built-in middleware.
RESTful API Creation:
Simplifies the process of building RESTful APIs, making it
ideal for backend development.
o Routing in Express.js ?
Router Methods:
app.get(): Handles GET requests.
app.post(): Handles POST requests.
app.put(): Handles PUT requests.
app.delete(): Handles DELETE requests.
Route Parameters:
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`User ID: ${userId}`);
});
Query Strings:
Query strings can be accessed via req.query. For example:
app.get('/search', (req, res) => {
const query = req.query.q;
res.send(`Search query: ${query}`);
});
Middleware in Routes:
You can use middleware functions to execute code for specific routes:
app.use('/users', (req, res, next) => {
console.log('Request received at /users');
next(); // Call the next middleware or route handler
});
Router Module:
A router module is a separate file where you define all your routes,
instead of writing them directly in the main server file. It helps keep
your code clean and organized, especially in larger applications.
You can create modular routes using express.Router() for better
organization:
const userRouter = express.Router();
userRouter.get('/', (req, res) => {
res.send('List of users');
});
userRouter.post('/', (req, res) => {
res.send('Create a user');
});
app.use('/users', userRouter);
o Router.all ?
The router.all() method in Express is used to handle all HTTP methods
(like GET, POST, PUT, DELETE, etc.) for a specific URL path. It acts as a catch-
all for any HTTP method that is sent to that route.
const express = require('express');
const app = express();
const router = express.Router();
// Middleware for all HTTP requests to '/example' inside the
router
router.all('/example', (req, res, next) => {
console.log('A request was made to /user/example');
next();
});
// GET and POST routes for '/example' inside the router
router.get('/example', (req, res) => {
res.send('This is the GET request to /user/example');
});
router.post('/example', (req, res) => {
res.send('This is the POST request to /user/example');
});
// Mount the router at '/user' path
app.use('/user', router);
// Start the server
app.listen(3000, () => {
console.log('Server is running on
<http://localhost:3000>');
});
How It Works
Using router.all('/example', ...) le
ts you set up code that will run for all types of HTTP requests to the
/example route.
app.use(router); connects the routes you set up in router
(like /example) to your main app.
Without it, the app won’t recognize or serve any of those
routes.
Here’s what happens step-by-step:
3. app.all:
When any request (GET, POST, PUT, DELETE, etc.)
goes to /example, app.all runs first.
It logs A request was made to /example.
Then, it calls next() to let the server know to keep
processing the request.
4. app.get and app.post:
If the request was a GET request, app.get handles it
and sends back "This is a GET request."
If the request was a POST request, app.post handles it
and sends back "This is a POST request."
o Alternatives to Express.js (briefly mention other frameworks) ?
not very imp jest for know
Koa.js
Developed by the creators of Express, Koa is a lightweight
framework that uses async/await and provides a minimalistic
approach with more control over middleware.
Hapi.js
A powerful and flexible framework designed for building
applications and services, Hapi emphasizes configuration over
code and offers built-in validation and caching features.
NestJS
A progressive Node.js framework that uses TypeScript and is
heavily inspired by Angular. It’s suitable for building scalable
server-side applications with a modular architecture.
o Opinionated & Unopinionated ?
Opinionated:
What it means: The tool or framework tells you how to do things. It
has its own set way of doing things and expects you to follow it.
Example: Ruby on Rails. It tells you exactly how to structure your
app and what tools to use.
Unopinionated:
What it means: The tool or framework doesn’t tell you how to do
things. It gives you freedom to choose how you want to build your app.
Example: Express.js. It doesn’t force any specific way of doing
things, so you can set things up the way you want.
Opinionated Unopinionated
Suggest ways to do things different ways to do the same thing
Usually offer a lot of bells & whistles Includes the bare necessities
Strict folder structure Structure folder how you want
Express.js ㊙️code lines
This is important in some cases
o const app = express();
Creates an instance of Express, which is used to set up routes, apply
middleware, and handle various HTTP methods such as GET, POST, PUT,
and DELETE.
o app.use(bodyParser.json())
app.use(bodyParser.json()) is used to convert the JSON data in incoming
requests into a JavaScript object. This parsed data is then stored in req.body,
so your Express app can easily access and work with the data sent by clients.
o app.use(bodyParser.urlencoded({ extended: true }))
You only need app.use(bodyParser.urlencoded({ extended: true }))
if you're handling form data or URL-encoded data. If your app doesn't process
forms or URL-encoded data, it isn't required.
extended: false allows for simpler, flat data (no nested objects or
arrays).
extended: true allows for more complex, nested data structures.
Express.js ㊙️Advanced
o PUT and PATCH HTTP methods
PUT: Replaces the entire resource with the provided data.
const express = require('express');
const app = express();
app.use(express.json());
let user = { id: 1, name: 'Alice', email:
'
[email protected]' };
// PUT: Replaces the entire user object
app.put('/user', (req, res) => {
user = req.body;
res.json(user);
});
// Start server for PUT example
app.listen(3000, () => console.log('PUT Server running at
<http://localhost:3000>'));
PATCH: Updates only the specified fields of a resource without
affecting other fields.
const express = require('express');
const app = express();
app.use(express.json());
let user = { id: 1, name: 'Alice', email:
'
[email protected]' };
// PATCH: Updates only the specified fields
app.patch('/user', (req, res) => {
Object.assign(user, req.body);
res.json(user);
});
// Start server for PATCH example
app.listen(3001, () => console.log('PATCH Server running
at <http://localhost:3001>'));
Feature PUT PATCH
Purpose Replaces the entire resource Updates only specified fields
Request Must include the complete
Can include partial resource data
Body resource data
Yes (same request results in Yes (same request results in the
Idempotency
the same state) same state)
When replacing the entire
Use Case When updating specific fields
object
{ "id": 1, "name":
{ "email":
Example "Bob", "email":
"
[email protected]" }
"
[email protected]" }
o Scope chaining (let vs. var) ?
Feature var let
Function scope or globally
Scope Block scope (within {})
scoped
Hoisted to the top of the Hoisted but not initialized
Hoisting function or global scope (ReferenceError if accessed
(initialized as undefined) before declaration)
Can be redeclared within the Cannot be redeclared within
Redeclaration
same scope the same block scope
Temporal Dead No TDZ; accessible before TDZ exists; not accessible
Zone (TDZ) declaration (undefined) before declaration
Used in older code; can lead
Preferred for block scope, safer
Usage to bugs due to function
and avoids hoisting issues
scoping
o Body-parser ?
Body-parser converts the incoming request body sent by the user into a
simple JavaScript object, making it easy to manipulate and access the data
within your application.
The line app.use(express.urlencoded({ extended: true })); is a
middleware function in Express that converts the body content of incoming
requests with URL-encoded data into a JavaScript object, allowing you to
easily access and manipulate the data.
o Binary data vs URL encoding vs Body parser
Body-parser focuses on converting incoming request data into usable
JavaScript objects for developers.
URL Encoding ensures that text can be safely transmitted over the
internet.
Binary Data is the fundamental way computers process and
understand all types of data internally.
o Session and cookies ?
Purpose: Both sessions and cookies are used to store information
about a user's interaction with a web application, allowing the
application to remember user data across requests.
Sessions: Work on the server side to maintain user data and state
securely and can hold more information. They expire after inactivity or
when the user logs out.
Cookies: Work on the client side and are used to store small amounts
of data, often related to user preferences or login status. They can
persist across browser sessions if configured to do so.
Feature Cookies Sessions
Storage
Client-side (browser) Server-side
Location
Much larger (depends on
Data Size Limited (up to 4 KB)
server)
Expiration Can be set (specific Usually time-based (inactivity)
Feature Cookies Sessions
date/time)
Less secure (exposed to More secure (data is on the
Security
client) server)
Store preferences, track
Use Case Store user state, authentication
activity
o What is MVC (Model-View-Controller) ?
The Model-View-Controller (MVC) framework is an architectural/design
pattern that separates an application into three main logical
components Model, View, and Controller.
Model
Role: Manages data-related logic, representing the data the user
interacts with.
Responsibilities:
Manages data through CRUD (Create, Read, Update,
Delete) operations.
Enforces business rules.
Notifies the View and Controller of any state changes.
Controller
Role: Acts as an intermediary between the View and Model,
handling user input and business logic.
Responsibilities:
Receives and interprets user input.
Updates the Model based on user actions.
Selects and displays the appropriate View.
View
Role: Handles the user interface (UI) logic, presenting data to
the user.
Responsibilities:
Renders data in a specific format for the user.
Displays UI elements.
Updates the display when the Model changes.
o View engines ?
View engines are tools that allow developers to dynamically generate HTML
pages in web applications.
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
res.render('index', { title: 'Home Page' });
});
o Why use res.render()?
res.render() is a method in Express that combines a specified template (like
EJS) with provided data to generate and send HTML content as a response to
the client.
app.get('/', (req, res) => {
res.render('index', { title: 'Home Page', message: 'Welcome
to the website!' });
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title><%= title %></title>
</head>
<body>
<h1><%= message %></h1>
<p>This is the home page.</p>
</body>
</html>
o res.render() vs res.json()
res.json(): Sends a JSON object to the client. The user sees raw
JSON data.
res.render(): Renders an HTML page. The user sees a formatted
web page with HTML elements.
o res.send() vs res.render()
res.send()
res.send(): This method sends a plain HTML file or string directly to
the client. It’s suitable for simple static HTML content, but it doesn’t
allow for dynamic templating.
app.get('/', (req, res) => {
res.send('<h1>Home Page</h1>');
});
res.render
res.render(): This method is used to render templates with data
before sending HTML to the client. It’s ideal when you’re using a view
engine to generate dynamic HTML content.
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
res.render('home', { title: 'Home Page' });
});
o res.render() is usually preferred in full web applications where templating
is required.
o res.send() is typically sufficient for simple or static responses.
o res.write()vs res.send()
res.write: Writes data to the response stream without ending it. Used
for sending partial responses in chunks.
res.write("Hello");
res.write(" World!");
res.end();
res.send: Sends a complete response to the client and automatically
sets headers like Content-Type.
res.send("Hello World!");
o res.locals and app.locals
res.locals
Scope: Specific to a single request-response cycle.
Usage: It is used to store data that is local to the current
request. This data is available during the request and can be
accessed in the response, or in the next middleware or route
handlers.
Example: You can set values in res.locals and access them
in the response or views (e.g., using a templating engine).
app.get('/', (req, res) => {
res.locals.user = { name: 'John Doe' }; // Data
for this request only
res.render('home'); // Render a view and use
`res.locals.user`
});
In this case, res.locals.user is only available for the current
request and response cycle.
app.locals
Scope: Global across the entire application.
Usage: It is used to store data that is available to all routes and
requests in the application. Data stored here is persistent
throughout the lifetime of the application.
Example: You can set values in app.locals for data or
settings that are globally accessible across all routes.
app.locals.siteName = 'My Awesome App'; // Global
data for the entire app
app.get('/', (req, res) => {
res.send(`Welcome to ${app.locals.siteName}`);
});
In this case, app.locals.siteName is available throughout the
entire application, in any route or middleware.
Property res.locals app.locals
Scope Specific to a single request-response Available globally for the
Property res.locals app.locals
cycle. entire application.
Store data that is only needed for the Store global settings or data
Usage
current request and response. for the whole app.
Data is cleared after the Data persists for the
Persistence
request/response cycle ends. lifetime of the application.
Node.js ♻️Architecture ?
o DIAGRAM
o Modular vs Module vs Modules
Module: A set of functions you want to include in your application.
Modular: The concept of organizing code into modules.
Modules: Modules are the reusable blocks of code that encapsulate
various functionalities in a Node application.
o Modules ?
A modules contains a specific functionality that can be easily reused within a
Node.js application.
Core modules in Node.js
Node.js comes with a set of built-in modules, known as core modules,
which provide essential functionalities for building applications.
fs Module
fs.mkdir : Create a new directory (folder) in the file
system.
Explanation of the Code
fs.mkdir: Creates a new directory
(folder) in the file system.
path.join(__dirname, '/text'):
path.join(): Constructs a file
path from multiple segments,
ensuring compatibility across
platforms (Windows, macOS,
Linux).
__dirname: Global variable
representing the current script's
directory.
'/text': The name of the folder
to be created, located in the
current directory.
Together, path.join(__dirname,
'/text') creates a path to the new 'text'
folder.
{} (Empty Options Object): Represents
options for folder creation (e.g.,
recursive), but here it’s empty.
Callback Function: Executes after
fs.mkdir completes:
err: Contains an error message if
an issue arises (e.g., folder
already exists, permission issues).
If an error occurs, it is thrown.
console.log('Folder
created.......'): Prints a
success message if the folder is
created without errors.
const fs = require('fs'); // Import file
system module
const path = require('path'); // Import path
module`
// Create a folder named 'text' in the
current directory
fs.mkdir(path.join(__dirname, '/text'), {},
(err) => {
if (err) throw err; //Stop on error
console.log('Folder created.......'); // Log
success
});
fs.writeFile : Write data to a file.
Explanation of the Code
Reading a File
**fs.readFile**: Asynchronously
reads file contents.
**path.join(__dirname, 'text',
'Hello.txt')**:
path.join(): Combines path
segments for cross-platform
compatibility.
**__dirname**: Current script's
directory.
**'text'**: Folder containing
the file.
**'Hello.txt'**: The file to
read.
Callback Function:
**err**: Error if reading fails
(e.g., file not found).
**data**: File contents if read
successfully.
Writing to a File
**fs.writeFile**: Writes data to a
file, creating it or overwriting it.
**path.join(__dirname, 'text',
'Hello.txt')**: Constructs the file
path.
**'Hello world'**: Data to write.
Callback Function:
**err**: Error if writing fails.
**console.log('File written
to.......')**: Success
message if written successfully.
const fs = require('fs'); // File system
module
const path = require('path'); // Module for
file paths`
// Write 'Hello world' to 'Hello.txt' in the
'text' folder
fs.writeFile(path.join(__dirname, 'text',
'Hello.txt'), 'Hello world', (err) => {
if (err) throw err; // Handle write errors
console.log('File written to.......'); //
Success message
});
fs.appendFile : method is used to append data to a
file.
const fs = require('fs'); // File system
module
const path = require('path'); // Path module`
// Append data to 'Hello.txt' in the 'text'
folder
fs.appendFile(path.join(__dirname, '/text',
'Hello.txt'), ' I love Node.js', (err) => {
if (err) throw err; // Throw error if append
fails
console.log('Data appended to file!'); // Log
success message
});
fs.readFile : Read the contents of a file
asynchronously.
Explanation
- **`path.join(__dirname, '/text',
'hello.txt')`**: Constructs the file
path to `hello.txt` based on the
directory of the current script.
- **`'utf-8'`**: Specifies that the
file should be read using UTF-8
encoding, which converts the file
content into a string.
Callback Function: After the read
operation completes:
err: If there is an error (like the
file not being found), it is thrown.
data: Contains the content of
hello.txt, which is logged to
the console.
const fs = require('fs'); // File system
module
const path = require('path'); // Path module`
// Read the content of 'hello.txt' in the
'text' folder
fs.readFile(path.join(__dirname, '/text',
'hello.txt'), 'utf-8', (err, data) => {
if (err) throw err; // Throw error if reading
fails
console.log(data); // Log the content of the
file
});
fs.rename : Rename a file.
Explanation
const fs = require('fs'); // Import the file
system module
const path = require('path'); // Import the
path module`
// Rename 'hello.txt' to 'helloworld.txt' in
the 'text' folder
fs.rename(
path.join(__dirname, '/text',
'hello.txt'), // Current file path
path.join(__dirname, '/text',
'helloworld.txt'), // New file path
(err) => { // Callback function
if (err) throw err; // Throw an error if the
operation fails
console.log('File renamed........'); // Log
success message
});
fs.unlink(): Delete a file.
http Module
Enables the creation of HTTP servers and clients.
const http = require('http');
// Create a basic HTTP server
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type':
'text/plain' });
res.end('Hello World\\n');
});
// Listen on port 3000
server.listen(3000, () => {
console.log('Server running at
<http://localhost:3000/>');
});
pathModule
Provides utilities for working with file and directory
paths.(for joining, resolving, parsing, formatting,
normalizing and manipulating paths )
Helps handle cross-platform file paths.
different type of path example
// Join paths
const fullPath = path.join('users', 'john',
'document.txt'); // Output:
'users/john/document.txt'
// Resolve an absolute path
const resolvedPath = path.resolve('users',
'john', 'document.txt'); // Outputs absolute
path
// Get the basename of a path
const baseName = path.basename(fullPath); //
Output: 'document.txt'
// Get the directory name
const dirName = path.dirname(fullPath); //
Output: 'users/john'
// Get the file extension
const extName = path.extname(fullPath); //
Output: '.txt'
// Normalize a path
const normalizedPath =
path.normalize('users//john//../john//documen
t.txt'); // Output: 'users/john/document.txt'
// Parse a path into an object
const parsedPath = path.parse(fullPath);
/* Output:
{
root: '',
dir: 'users/john',
base: 'document.txt',
ext: '.txt',
name: 'document'
}
*/
// Check if a path is absolute
const isAbsolutePath =
path.isAbsolute(fullPath); // Output: true or
false
const path = require('path');
const filePath = path.join(__dirname, 'file.txt');
console.log(filePath);
event Module
Provides a way to work with events and event-driven
programming.
Allows you to create and manage event emitters.
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {
console.log('An event occurred!');
});
myEmitter.emit('event');
os Module
os.platform(): Get the operating system platform
(e.g., 'win32', 'linux').
const os = require('os');
console.log(os.platform()); // e.g., 'win32',
'linux`
os.cpus(): Get information about the CPU(s) in the
system.
const os = require('os');
console.log(os.cpus());
os.freemem(): Get the amount of free memory in
bytes.
const os = require('os');
console.log(os.freemem());
os.totalmem(): Get the total amount of memory in
bytes.
const os = require('os');
console.log(os.totalmem());
os.homedir(): Get the home directory of the current
user.
const os = require('os');
console.log(os.homedir());
url Module
Serialized URL:
myUrl.href and myUrl.toString() give you the full
URL as a string.
//SERIALIZED URL
console.log(myUrl.href);
console.log(myUrl.toString());
Host Information:
myUrl.host returns the host (domain and port).
console.log(myUrl.host);
myUrl.hostname returns just the domain
without the port.
console.log(myUrl.hostname);
Path and Query:
myUrl.pathname retrieves the path of the URL.
console.log(myUrl.pathname);
myUrl.search retrieves the query string
(everything after the ?).
console.log(myUrl.search);
Search Parameters:
myUrl.searchParams returns a
URLSearchParams object, allowing for easy
manipulation of the query string.
myUrl.searchParams.append('abc', '123');
console.log(myUrl.searchParams);
You can add parameters using append() and
loop through them with forEach().
myUrl.searchParams.forEach((value, name) => {
console.log(`${name}: ${value}`);
});
Local Modules
Custom modules created for your specific application.
You can define your own functionality and export it for use in
other files.
Third-Party Modules
Modules developed by the community and available through
the npm registry.
Examples: express (web framework), mongoose (MongoDB
object modeling), lodash (utility library).
o Type Of Modules ?
Core modules
These are built-in modules that come with Node.js. They provide
essential functionalities and are available without any additional
installation.
fs Module: For interacting with the file system.
fs.mkdir : Create a new directory (folder) in the file
system.
Explanation of the Code
fs.mkdir: Creates a new directory
(folder) in the file system.
path.join(__dirname, '/text'):
path.join(): Constructs a file
path from multiple segments,
ensuring compatibility across
platforms (Windows, macOS,
Linux).
__dirname: Global variable
representing the current script's
directory.
'/text': The name of the folder
to be created, located in the
current directory.
Together, path.join(__dirname,
'/text') creates a path to the new 'text'
folder.
{} (Empty Options Object): Represents
options for folder creation (e.g.,
recursive), but here it’s empty.
Callback Function: Executes after
fs.mkdir completes:
err: Contains an error message if
an issue arises (e.g., folder
already exists, permission issues).
If an error occurs, it is thrown.
console.log('Folder
created.......'): Prints a
success message if the folder is
created without errors.
const fs = require('fs'); // Import file
system module
const path = require('path'); // Import path
module`
// Create a folder named 'text' in the
current directory
fs.mkdir(path.join(__dirname, '/text'), {},
(err) => {
if (err) throw err; //Stop on error
console.log('Folder created.......'); // Log
success
});
fs.writeFile : Write data to a file.
Explanation of the Code
Reading a File
**fs.readFile**: Asynchronously
reads file contents.
**path.join(__dirname, 'text',
'Hello.txt')**:
path.join(): Combines path
segments for cross-platform
compatibility.
**__dirname**: Current script's
directory.
**'text'**: Folder containing
the file.
**'Hello.txt'**: The file to
read.
Callback Function:
**err**: Error if reading fails
(e.g., file not found).
**data**: File contents if read
successfully.
Writing to a File
**fs.writeFile**: Writes data to a
file, creating it or overwriting it.
**path.join(__dirname, 'text',
'Hello.txt')**: Constructs the file
path.
**'Hello world'**: Data to write.
Callback Function:
**err**: Error if writing fails.
**console.log('File written
to.......')**: Success
message if written successfully.
const fs = require('fs'); // File system
module
const path = require('path'); // Module for
file paths`
// Write 'Hello world' to 'Hello.txt' in the
'text' folder
fs.writeFile(path.join(__dirname, 'text',
'Hello.txt'), 'Hello world', (err) => {
if (err) throw err; // Handle write errors
console.log('File written to.......'); //
Success message
});
fs.appendFile : method is used to append data to a
file.
const fs = require('fs'); // File system
module
const path = require('path'); // Path module`
// Append data to 'Hello.txt' in the 'text'
folder
fs.appendFile(path.join(__dirname, '/text',
'Hello.txt'), ' I love Node.js', (err) => {
if (err) throw err; // Throw error if append
fails
console.log('Data appended to file!'); // Log
success message
});
fs.readFile : Read the contents of a file
asynchronously.
Explanation
- **`path.join(__dirname, '/text',
'hello.txt')`**: Constructs the file
path to `hello.txt` based on the
directory of the current script.
- **`'utf-8'`**: Specifies that the
file should be read using UTF-8
encoding, which converts the file
content into a string.
Callback Function: After the read
operation completes:
err: If there is an error (like the
file not being found), it is thrown.
data: Contains the content of
hello.txt, which is logged to
the console.
const fs = require('fs'); // File system
module
const path = require('path'); // Path module`
// Read the content of 'hello.txt' in the
'text' folder
fs.readFile(path.join(__dirname, '/text',
'hello.txt'), 'utf-8', (err, data) => {
if (err) throw err; // Throw error if reading
fails
console.log(data); // Log the content of the
file
});
fs.rename : Rename a file.
Explanation
const fs = require('fs'); // Import the file
system module
const path = require('path'); // Import the
path module`
// Rename 'hello.txt' to 'helloworld.txt' in
the 'text' folder
fs.rename(
path.join(__dirname, '/text',
'hello.txt'), // Current file path
path.join(__dirname, '/text',
'helloworld.txt'), // New file path
(err) => { // Callback function
if (err) throw err; // Throw an error if the
operation fails
console.log('File renamed........'); // Log
success message
});
fs.unlink(): Delete a file.
http Module: For creating web servers.
Enables the creation of HTTP servers and clients.
const http = require('http');
// Create a basic HTTP server
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type':
'text/plain' });
res.end('Hello World\\n');
});
// Listen on port 3000
server.listen(3000, () => {
console.log('Server running at
<http://localhost:3000/>');
});
pathModule: For handling and transforming file paths.
Provides utilities for working with file and directory
paths.(for joining, resolving, parsing, formatting,
normalizing and manipulating paths )
Helps handle cross-platform file paths.
different type of path example
// Join paths
const fullPath = path.join('users', 'john',
'document.txt'); // Output:
'users/john/document.txt'
// Resolve an absolute path
const resolvedPath = path.resolve('users',
'john', 'document.txt'); // Outputs absolute
path
// Get the basename of a path
const baseName = path.basename(fullPath); //
Output: 'document.txt'
// Get the directory name
const dirName = path.dirname(fullPath); //
Output: 'users/john'
// Get the file extension
const extName = path.extname(fullPath); //
Output: '.txt'
// Normalize a path
const normalizedPath =
path.normalize('users//john//../john//documen
t.txt'); // Output: 'users/john/document.txt'
// Parse a path into an object
const parsedPath = path.parse(fullPath);
/* Output:
{
root: '',
dir: 'users/john',
base: 'document.txt',
ext: '.txt',
name: 'document'
}
*/
// Check if a path is absolute
const isAbsolutePath =
path.isAbsolute(fullPath); // Output: true or
false
const path = require('path');
const filePath = path.join(__dirname, 'file.txt');
console.log(filePath);
event Module: For operating system-related utility methods.
Provides a way to work with events and event-driven
programming.
Allows you to create and manage event emitters.
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {
console.log('An event occurred!');
});
myEmitter.emit('event');
os Module
os.platform(): Get the operating system platform
(e.g., 'win32', 'linux').
const os = require('os');
console.log(os.platform()); // e.g., 'win32',
'linux`
os.cpus(): Get information about the CPU(s) in the
system.
const os = require('os');
console.log(os.cpus());
os.freemem(): Get the amount of free memory in
bytes.
const os = require('os');
console.log(os.freemem());
os.totalmem(): Get the total amount of memory in
bytes.
const os = require('os');
console.log(os.totalmem());
os.homedir(): Get the home directory of the current
user.
const os = require('os');
console.log(os.homedir());
url Module
Serialized URL:
myUrl.href and myUrl.toString() give you the full
URL as a string.
//SERIALIZED URL
console.log(myUrl.href);
console.log(myUrl.toString());
Host Information:
myUrl.host returns the host (domain and port).
console.log(myUrl.host);
myUrl.hostname returns just the domain
without the port.
console.log(myUrl.hostname);
Path and Query:
myUrl.pathname retrieves the path of the URL.
console.log(myUrl.pathname);
myUrl.search retrieves the query string
(everything after the ?).
console.log(myUrl.search);
Search Parameters:
myUrl.searchParams returns a
URLSearchParams object, allowing for easy
manipulation of the query string.
myUrl.searchParams.append('abc', '123');
console.log(myUrl.searchParams);
You can add parameters using append() and
loop through them with forEach().
myUrl.searchParams.forEach((value, name) => {
console.log(`${name}: ${value}`);
});
Local Modules
se are modules that you create in your own Node.js applications.
Third-Party Modules
These are modules developed by the community and available via the
Node Package Manager (NPM)
Express: A web framework for building web applications.
Lodash: A utility library for working with arrays, objects, and
more.
Mongoose: An ODM (Object Data Modeling) library for
MongoDB.
o Module & function ?
A module contains a specific functionality that can be easily reused
within a Node.js application
Ideally in node.js, a JavaScript file can be treated as a module
A module is a border concept that encapsulates functionality, while a
function is a specific set of instructions within that module.
Module can contain multiple functions and variables
o // greetings.js
o
o // Function to return a greeting message
o const greet = (name) => `Hello, ${name}!`;
o
o // Export the greet function
o module.exports = greet;
o
o Module vs function ?
Feature Module Function
Definition Self-contained code unit Block of code performing a task
Purpose Organizes reusable code Encapsulates logic
Scope Can contain functions, variables Executes specific tasks
Exporting Exports multiple items Returns a single value
Importing Imported into other modules Called directly by name
Usage Structures applications Used for operations
Example math.js with arithmetic functions add(a, b) for summation
o What is MVC (Model-View-Controller) ?
The Model-View-Controller (MVC) framework is an architectural/design
pattern that separates an application into three main logical
components Model, View, and Controller.
Model
Role: Manages data-related logic, representing the data the user
interacts with.
Responsibilities:
Manages data through CRUD (Create, Read, Update,
Delete) operations.
Enforces business rules.
Notifies the View and Controller of any state changes.
Controller
Role: Acts as an intermediary between the View and Model,
handling user input and business logic.
Responsibilities:
Receives and interprets user input.
Updates the Model based on user actions.
Selects and displays the appropriate View.
View
Role: Handles the user interface (UI) logic, presenting data to
the user.
Responsibilities:
Renders data in a specific format for the user.
Displays UI elements.
Updates the display when the Model changes.
o npm init ?
npm init is a command used to create a new package.json file for a Node.js
project. This file contains metadata about the project, including its name,
version, dependencies, and scripts.
npm init vs npm init -y
npm init:
Runs an interactive process where you are prompted to
enter details about your project (name, version,
description, etc.).
Allows you to customize each field according to your
preferences.
npm init -y:
Skips the interactive prompts and automatically
generates a package.json file with default values.
Uses default settings for all fields, such as the name and
version.
o npm vs. npx ?
npm
Purpose: Manages packages for Node.js projects.
Usage:
Install packages: npm install <package-name>
Manage dependencies in package.json.
Publish packages to the npm registry.
Global vs. Local: Can install packages globally (available
system-wide) or locally (available only in the project).
npx
Purpose: Executes Node.js packages directly without needing
to install them.
Usage:
Run a package without installing it: npx <package-
name>
Ideal for one-time use or running CLI tools that you
don’t want to install globally.
Convenience: Automatically downloads the package if it’s not
available locally or globally.
Feature npm npx
Manages and installs Executes Node.js packages
Purpose
Node.js packages directly
Feature npm npx
Installs packages locally
Installation Runs packages without installing
or globally
npm install <package-
Usage name>
npx <package-name>
Project Manages package.json Not used for managing
Management and dependencies dependencies
Runs packages from the current
Can install packages
Global Access context or downloads them
globally
temporarily
Typical Use Setting up projects and Running one-time scripts or CLI
Case managing dependencies tools
o Nvm
1.Definition: NVM stands for "Node Version Manager."
2.Purpose: It's a tool for installing, managing, and switching between
different versions of Node.js.
3. Usefulness: Particularly useful for:
Testing applications against multiple Node.js versions.
Handling projects that require different Node.js versions.
4. Flexibility: Allows you to easily switch between Node.js versions as
needed.
5. Compatibility: Ensures your applications work correctly with the
specific Node.js versions they were developed with.
o node_modules folder ?
node_modules folder contains all the dependences of the node project
o NPM (Node Package Manager) ?
NPM is used to manage the dependences for your Node project
Install 3rd party packages (like express, lodash, mongoose, etc.)
(frameworks, libraries, tools, etc)
Packages get stored in the “node_modules” folder
All dependencies are listed in a “package.json” file
NPM script can be created to run certain tasks such as run a server.
o package.json ?
The package.json file contains project metadata ( information about the project
). For example, project name, version, description, author, license etc.
{
"name": "my-project", // The name of your
project
"version": "1.0.0", // The version of your
project
"description": "A simple Node.js project", // A brief
description of the project
"main": "app.js", // The entry point of
your application
"scripts": { // Scripts that can be
run with npm
"start": "node app.js", // Command to start the
application
"test": "echo \\"Error: no test specified\\" && exit
1" // Command for running tests
},
"keywords": ["node", "express"], // Keywords for
searchability
"author": "Your Name", // The author's name
"license": "MIT", // License type for the
project
"dependencies": { // Packages required for
the application to run
"express": "^4.17.1" // Express framework as
a dependency
},
"devDependencies": { // Packages needed only
during development
"nodemon": "^2.0.4" // Nodemon for auto-
restarting the server during development
}
}
o package-lock.json ?
package-lock.json is an automatically generated file in Node.js projects that
locks dependency versions to ensure consistent installations and faster
package retrieval.
{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 1,
"dependencies": {
"express": {
"version": "4.17.1",
"resolved":
"<https://registry.npmjs.org/express/-/express-4.17.1.tgz>",
"integrity": "sha512-Z0d...",
"dev": false,
"engines": {
"node": ">=0.10.0"
},
"dependencies": {
"body-parser": {
"version": "1.19.0",
"resolved": "<https://registry.npmjs.org/body-
parser/-/body-parser-1.19.0.tgz>",
"integrity": "sha512-...",
"dev": false
}
}
}
}
}
o Scripts in package.json
Scripts in package.json allow you to define custom commands that
automate tasks.
They make it easier to manage and execute common commands (like
starting a server or running tests) with a simple npm run <script-
name>.
HTTP - Middleware - URL
o HTTP Headers ?
HTTP Headers are an important part of the API request and response as they
represent the meta-data associated with the API request and response.
Headers carry information for the request and Response Body
o HTTP Response (status code)
1xx: Informational
100 Continue: Initial part of a request has been received and the client
can continue with the request.
2xx: Success
201 Created: A resource has been successfully created, often used in
response to a POST request.
200 OK: The request was successful, and the server returned the
requested data.
3xx: Redirection
301 Moved Permanently: The requested resource has been moved to
a new URL permanently.
302 Found: The requested resource is temporarily located at a
different URL.
4xx: Client Errors
400 Bad Request: The server cannot process the request due to a client
error (e.g., malformed request syntax).
401 Unauthorized: The request requires user authentication.
403 Forbidden: The server understands the request but refuses to
authorize it.
404 Not Found: The requested resource could not be found on the
server.
408 Request Timeout: The server timed out waiting for the request.
5xx: Server Errors
Status Code Description
200 OK
201 Created
301 Moved Permanently
302 Found
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
408 Request Timeout
500 Internal Server Error
503 Service Unavailable
o HTTP Methods ?
Example
// 1. GET: Retrieve data
app.get('/users', (req, res) => {
res.send('List of users');
});
// 2. POST: Send data (create)
app.post('/users', (req, res) => {
res.send('User created');
});
// 3. PUT: Update data (or create)
app.put('/users/:id', (req, res) => {
res.send(`User ${req.params.id} updated`);
});
// 4. DELETE: Remove data
app.delete('/users/:id', (req, res) => {
res.send(`User ${req.params.id} deleted`);
});
// 5. PATCH: Partially update data
app.patch('/users/:id', (req, res) => {
res.send(`User ${req.params.id}'s email updated`);
});
// 6. OPTIONS: Check available methods
app.options('/users', (req, res) => {
res.send('GET, POST, PUT, DELETE, PATCH');
});
GET: When you want to get some data from the server
POST: Send data (create)
PUT: Update data (or create)
DELETE: Remove data
PATCH: Partially update data
OPTIONS: Check available methods
HEAD: Retrieve headers only
o HTTP Options ?
HTTP OPTIONS Method: It's used to find out what HTTP methods
(like GET, POST, PUT, DELETE) are allowed for a particular URL or
endpoint on the server.
Purpose: It helps clients (like browsers or applications) know what
actions they can perform on a specific resource.
o Middleware ?
Middleware in Express.js refers to functions that run during the request-
response cycle. They can modify requests and responses, end the cycle, or
pass control to the next middleware.
Example
app.use((req, res, next) => {
console.log("Middleware-1");
res.end("Ending here"); // Ends the request-response
cycle
next(); // This next() is ignored because res.end has
already sent a response
Request Processing: Middleware can handle tasks like logging,
authentication, or parsing request data before reaching the route
handler.
Response Handling: They can modify responses, such as setting
headers or formatting data before sending it back to the client.
Error Handling: Middleware can catch errors during processing.
Error-handling functions take four arguments: (err, req, res,
next).
Chaining: You can chain multiple middleware functions. Each can call
next() to pass control to the next one.
o Morgan
Morgan is a middleware for logging HTTP requests in Node.js applications. It
is commonly used in Express.js applications to monitor and log details about
incoming requests, such as method, URL, status code, response time, etc.
Why Use Morgan?
1. Debugging: It helps track what requests your server is handling
and how it's responding.
2. Analytics: Logs can be analyzed to understand request patterns
or traffic.
3. Error Tracking: Quickly identify problematic requests by
inspecting logs.
Example
o Using Express middleware
o javascript
o Copy code
o const express = require('express');
o const app = express();
o const port = 3000;
o
o // Simple logging middleware
o app.use((req, res, next) => {
o console.log(`Request: ${req.method} ${req.url}`);
o next(); // Pass control to the next middleware
o });
o
o // Middleware to parse JSON
o app.use(express.json());
o
o // Sample route
o app.post('/data', (req, res) => {
o res.json({ received: req.body }); // Respond with the
received data
o });
o
o // Start server
o app.listen(port, () => {
o console.log(`Server running at <http://localhost>:$
{port}`);
o });
o Example of common middleware ?
Logging Middleware
Logs the details of incoming requests.
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // Pass to the next middleware
});
Body Parser Middleware
Parses incoming JSON requests.
const express = require('express');
const app = express();
app.use(express.json()); // Parses application/json
Cookie Parser Middleware
Parses cookies attached to the client request.
const cookieParser = require('cookie-parser');
app.use(cookieParser()); // Enables cookie parsing
Static File Middleware
Serves static files like images, CSS, and JavaScript.
app.use(express.static('public')); // Serves files from
the 'public' directory
Error Handling Middleware
Catches and handles errors that occur during request processing.
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!'); // Respond
with an error message
});
o Middleware Chaining ?
Middleware chaining in Node.js involves executing multiple
middleware functions in sequence for a single request.
Middleware functions process the request object (req), response object
(res), and optionally pass control to the next middleware using
next().
Example:
app.use((req, res, next) => {
console.log('First middleware');
next(); // Passes control to the next middleware
});
app.use((req, res) => {
res.send('Response from second middleware');
});
o URL/URI
URI (Uniform Resource Identifier) identifies a resource either by
location (URL) or by name.
URL (Uniform Resource Locator) is a type of URI that specifies the
location of a resource on the internet.
o URI
URI (Uniform Resource Identifier) is a string that identifies a resource on
the internet. It can refer to anything, like a web page, file, or image, and helps
locate it.
For example:
http://example.com/resource is a URI where http:// is the
scheme, and example.com/resource is the path to the resource.
o URL vs Headers ?
URL:
What it is: A web address that tells your browser where to go.
Example: https://example.com/home is a URL that points
to the "home" page of the "example.com" website.
Headers:
What they are: Additional pieces of information sent along
with a web request. They help describe what you want or give
context.
Example: When your browser requests a webpage, it sends
headers that might include:
What type of browser you are using (like Chrome or
Firefox).
What language you prefer for the response.
o URL (Uniform Resource Locator) ?
It is the web address used to access specific resources on the internet
eg: https://example.com/about
https:// - Protocol (secure HTTP)
(Hypertext Transfer Protocol Secure)
example.com - Domain name
/about - Path to a specific resource or page on the site
DOMAIN: user-friendly version of an IP address.
o URL encoding ?
URL encoding is like turning your words into a secret code that the internet
can understand.
Conversion: Changes regular text into a special format that uses codes
(like %20 for spaces).
Purpose: This format is used to safely transmit text over the
internet, ensuring that special characters don’t cause confusion.
Example: The phrase "hello world" becomes "hello%20world".
o URL fragment
A URL fragment is the part of a URL that comes after the # symbol. It is
used to point to a specific section or element within a webpage. Fragments are
not sent to the server but are handled by the browser or JavaScript on the
client side.
Example
URL: https://example.com/page.html#section1
Fragment: #section1
It might refer to a section with the ID section1 in the HTML.
Purpose
Navigate to specific parts of a page.
Enable single-page applications (SPAs) to track views or state without
reloading.
app.use(), app.all(), and app.set()
o app.use() : Adds middleware to handle requests for all routes.
app.use() is a middleware function that is executed for every request to the
server. It can be used to define middleware for processing all incoming
requests.
Example:
const express = require('express');
const app = express();
// Middleware that runs for all routes
app.use((req, res, next) => {
console.log('Request received');
next(); // Pass control to the next middleware or route
});
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(3000);
o app.all() : handles any HTTP method (like GET, POST, PUT, DELETE) for
the same route.
app.all() is used to define a route handler that will handle all HTTP
methods (GET, POST, PUT, DELETE, etc.) for a specific route.
Example:
app.all('/user', (req, res) => {
res.send('Handling all methods for /user');
});
In this example, no matter if the request is a GET, POST, or any other method,
it will go through this route.
o app.set() : Sets application-level variables or configurations.
app.set() is used to set application-level variables and configurations, such
as the view engine, port, or other settings.
Example:
app.set('port', 3000);
app.listen(app.get('port'), () => {
console.log(`Server running on port ${app.get('port')}`);
});
Setting a port:
app.set('port', 3000);
Setting the view engine:
app.set('view engine', 'ejs');
Spawn() vs Fork()
o spawn: Creates a new process to run external commands (like system
commands). Use spawn when you want to run a command that is not
JavaScript (like listing files).
o fork: Creates a new process to run JavaScript code from another file. Use
fork when you want to run another JavaScript file.
o Visual Analogy: Chefs and Kitchens
Using spawn
Scenario: The main chef in Kitchen A goes to Kitchen B to perform a
specific task.
Process:
Chef A (Main Chef) goes to Kitchen B to run an external
command (like ls).
After completing the task, Chef A returns to Kitchen A with the
results.
Key Point: The same chef performs a different task in another kitchen
without further interaction.
Using fork
Scenario: A new chef is assigned to Kitchen B for a different recipe.
Process:
Chef A (Main Chef) sends a new Chef B to Kitchen B to
execute a JavaScript file (like childScript.js).
Chef B can communicate back to Chef A about progress or
results.
Key Point: A new chef (Chef B) performs the task, allowing ongoing
communication between kitchens.
Summary of Key Differences
In spawn:
The main chef executes a command in another kitchen (one-
time task).
In fork:
A new chef runs JavaScript code in another kitchen (ongoing
interaction).
o Spawn()
The spawn() method is used to launch a new process with a given command.
It allows you to execute external commands and interact with the child
process’s input and output streams in real time.
Features
Real-time Streaming: spawn() streams data between the
parent and child process in real time, making it suitable for
long-running processes.
Raw I/O: It provides access to raw input and output streams
(stdin, stdout, stderr).
Independent Process: The child process runs independently of
the parent process.
Example
The ls command is used in Unix-based systems (like Linux and
macOS) to list the contents of a directory.
l:
Meaning: Stands for "long format."
Details: Displays detailed information about each file or
directory in the listing.
This includes permissions, number of links,
owner name, group name, file size, last
modification date, and file name.
h:
Meaning: Stands for "human-readable."
Details: Used in conjunction with l to display file sizes
in a more understandable format, such as:
K for kilobytes
M for megabytes
G for gigabytes
For example, instead of showing 2048 for a file size, it
would display 2K.
// Import the spawn function from the child_process
module
const { spawn } = require('child_process');
// Use spawn to run the 'ls' command to list files in the
current directory
const ls = spawn('ls', ['-lh']); // '-lh' gives a
detailed list
// Listen for data coming from the stdout of the child
process
ls.stdout.on('data', (data) => {
// Print the output received from the child process
console.log(`Output: ${data}`);
});
// Listen for any errors coming from the stderr of the
child process
ls.stderr.on('data', (data) => {
// Print any errors received from the child process
console.error(`Error: ${data}`);
});
// Listen for the child process to close
ls.on('close', (code) => {
// Print the exit code of the child process
console.log(`Child process exited with code ${code}`);
});
Visualization for spawn
Roles:
Chef A: The main chef, representing your main Node.js
program. He goes to Kitchen B to execute a command but
primarily operates from Kitchen A.
Process Flow in spawn
2. Preparation: Setting Up the Command
Statement: "I will go to Kitchen B to run the ls
command."
Code:
javascript
Copy code
const { spawn } =
require('child_process'); // Import the spawn
function
const ls = spawn('ls', ['-lh']); // Prepare
to run the 'ls' command
3. Execution in Kitchen B
Action: Chef A executes the command in Kitchen B.
Code:
javascript
Copy code
// Listen for output data from the child
process
ls.stdout.on('data', (data) => {
console.log(`Output: ${data}`); //
Collect the results and log them
});
4. Error Handling
Action: If there’s an error during execution, Chef A
collects error messages.
Code:
javascript
Copy code
// Listen for error output from the child
process
ls.stderr.on('data', (data) => {
console.error(`Error: ${data}`); // Log
any errors encountered
});
5. Return to Kitchen A
Completion Notification: Chef A returns to Kitchen A
with the output or error information.
Code:
javascript
Copy code
// Listen for when the child process closes
ls.on('close', (code) => {
console.log(`Child process exited with
code ${code}`); // Log the exit code
indicating completion
});
Summary of spawn Interaction
Chef A (the main chef) prepares to execute a command in
another kitchen (Kitchen B).
Execution: Chef A goes to Kitchen B to run the command.
Output Handling: Chef A collects results or error messages
and logs them.
Return: After execution, Chef A returns to Kitchen A with the
results.
Completion Notification: Chef A receives a notification (exit
code) indicating whether the operation was successful or if
there were issues.
Final Statement: "The command has finished, and I received
the output/error code.
o Fork()
The fork() method is a specialized version of spawn() that is specifically
designed for spawning new Node.js processes. It creates a new instance of the
V8 engine to run a separate Node.js script.
Features:
IPC (Inter-Process Communication): fork() establishes a
communication channel (IPC) between the parent and child
process, allowing for message passing.
Optimized for Node.js: It is optimized for spawning new
Node.js processes, inheriting the environment and execution
context.
Separate V8 Instance: Each forked process has its own V8
instance, making it more isolated.
Example
File: parent.js
// Import the fork function from the child_process module
const { fork } = require('child_process');
// Fork a new child process to run 'childScript.js'
const child = fork('childScript.js');
// Listen for messages coming from the child process
child.on('message', (message) => {
// Print the message received from the child
console.log(`Received from child: ${message}`);
});
// Send a message to the child process
child.send('Hello from parent');
File: childScript.js
// Listen for messages coming from the parent process
process.on('message', (message) => {
// Print the message received from the parent
console.log(`Received from parent: ${message}`);
// Send a response back to the parent process
process.send('Hello from child');
});
Visualization for fork
Roles:
Chef A: The main chef, representing your main Node.js
program.
Chef B: A new chef assigned to execute a specific recipe
(JavaScript code) from another file.
Process Flow in fork
3. Preparation: Starting a New Child Process
Statement: "I will send Chef B to Kitchen B to execute
the code in childScript.js."
Code:
javascript
Copy code
const { fork } = require('child_process'); //
Import the fork function
const child = fork('childScript.js'); //
Start a new child process to run
childScript.js
4. Communication with the Child Process
Action: Chef A sends a message to Chef B in Kitchen
B.
Code:
javascript
Copy code
child.send('Hello from parent'); // Chef A
sends a message to Chef B
5. Receiving Messages from the Child
Action: Chef A listens for messages from Chef B.
Code:
javascript
Copy code
child.on('message', (message) => {
console.log(`Received from child: $
{message}`); // Chef A receives and logs the
message from Chef B
});
6. Handling Completion Notification
Completion Notification: When Chef B finishes the
task, Chef A is informed about the exit status.
Code:
javascript
Copy code
child.on('exit', (code) => {
console.log(`Child process exited with
code ${code}`); // Chef A logs the exit code
indicating completion
});
Summary of fork Interaction
Chef A (the main chef) prepares to send Chef B to execute a
separate JavaScript file.
Starting the Process: Chef A forks a new process to run
childScript.js.
Communication: Chef A can send messages to Chef B and
receive responses.
Completion Notification: After Chef B completes the task,
Chef A is notified of the exit code.
Final Statement: "The task is finished, and I received the exit
code from Chef B."
cluster.fork()
The cluster.fork() method is used in the Node.js Cluster module to create new
worker processes that run the same Node.js application instance. It is typically used to
take advantage of multi-core systems by distributing the workload across multiple
processes.
o How cluster.fork() Works
Master Process:
The main process in Node.js that starts everything.
It creates worker processes.
Worker Processes:
Each cluster.fork() makes a new worker process.
These workers run the same app but handle different tasks.
Communication:
Workers and the master can send messages to each other.
o Example
o const cluster = require('cluster');
o
o if (cluster.isMaster) {
o // Master process code
o console.log(`Master process is running with PID: $
{process.pid}`);
o
o // Fork worker processes
o for (let i = 0; i < 4; i++) { // Number of workers to spawn
o cluster.fork();
o }
o } else {
o // Worker process code
o console.log(`Worker process started with PID: $
{process.pid}`);
o }
o
Domain?
o What is a Domain?
A domain is a unique name that identifies a website on the internet.
Example: In the web address www.example.com, "example.com" is the
domain name.
o Domain port flow
A domain (like example.com) is a name that points to a website's address on
the internet.
What is a Port?
A port is a virtual entry point for network communication, used by different
services (e.g., port 80 for HTTP).
Domain Port Flow
1. User Request: You enter a website address in your browser.
2. Find Address: The browser looks up the domain to find its IP address.
3. Connect to Server: The browser connects to the server using a
specific port (like port 80 for HTTP).
4. Server Responds: The server listens for requests on that port and
sends back the webpage.
5. Finish Connection: After the webpage is sent, the connection may
close or stay open for more requests.
o Garbage collection
Garbage collection in Node.js is an automatic memory management process
that helps reclaim memory occupied by objects that are no longer in use,
preventing memory leaks and optimizing performance.
o Trace
Tracing is about following the execution path and understanding what
happens during runtime.
o Exit code in node
What it is: An exit code shows how a program finished running.
Common Codes:
0: Success (no errors).
1: General error (something went wrong).
Other Codes: Indicate specific errors.
Summary
Use process.exit(code) to end a program.
After calling process.exit(), no subsequent code will be
executed.
The Node.js process ends immediately, so anything following
that call is ignored.
0 means success; 1 means an error.
Use
Immediate Termination: process.exit() stops the Node.js
process immediately, preventing any further code execution
and ensuring a clean exit.
Error Handling: It is commonly used to terminate the
application with a specific exit code, indicating success (0) or
failure (non-zero) when encountering errors.
Example
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
process.exit(1); // Exit with an error code
}
console.log('File data:', data);
process.exit(0); // Exit with success code
});
// This code will NOT run if process.exit() is called
console.log('This line will not be executed.');
o express.static
Definition: express.static is a built-in middleware function in Express that
serves static files, such as HTML, CSS, JavaScript, images, and other assets,
directly to the client.
Usage: It allows you to specify a directory from which static files can be
served, making it easy to manage and serve client-side resources.
Streams and Asynchronous Operations ?
o Buffer class ?
Node.js cannot control the pace of which data arrives in the stream
It can only decide when is the right time to send the the data for
processing
If there is data already processed or too little data to process, Node puts
the arriving data in a buffer.
o const buffer = Buffer.from("skjghks");
o
o console.log(buffer); // Output: <Buffer 73 6b 6a 67 68 6b 73>
o
o // Convert buffer back to string
o const str = buffer.toString();
o console.log(str); // Output: "skjghks"
o
o // Access individual bytes
o console.log(buffer[0]); // Output: 115 (ASCII code for 's')
o console.log(buffer[1]); // Output: 107 (ASCII code for 'k')
o
o Stream ?
A stream is a sequence of data that is being moved from one point to
another over.
eg: a stream of data over the internet being moved from one computer to
another
eg: a stream of data being in transferred from one file to another within the
same computer
Process stream of data in chunks as they arrive instead of waiting for
the entire data to be available before processing
eg: watching a video on youtube
o Duplex stream
Duplex streams enable two-way data flow, making them versatile for
various applications in Node.js.
They handle both reading and writing, allowing for efficient
communication between different parts of your application.
o stream and a duplex stream ?
Feature Stream Duplex Stream
Can be either readable or
Direction Can read and write simultaneously.
writable.
Includes readable, writable, A specific type of stream that is both
Types
and duplex streams. readable and writable.
Suitable for one-way data Suitable for two-way communication
Use Case flow (e.g., reading from a file (e.g., TCP sockets, inter-process
or writing to a file). communication).
Readable for reading data, Duplex stream that combines both
Examples
Writable for writing data. reading and writing capabilities.
o Type of Streams
Explained
1.Readable Streams:
Allow reading data from a source.
Data can be consumed piece by piece.
Example: fs.createReadStream() reads data from a
file.
2. Writable Streams:
Allow writing data to a destination.
Data can be written piece by piece.
Example: fs.createWriteStream() writes data to a
file.
3. Duplex Streams:
Allow both reading and writing of data.
Can be used for bi-directional communication.
Example: A TCP socket, where you can both send and
receive data.
4. Transform Streams:
A type of duplex stream that can modify or transform
the data as it is read and written.
Example: zlib.createGzip() compresses data as it is
being read or written.
Readable Streams: Read data from a source.
Writable Streams: Write data to a destination.
Duplex Streams: Read and write data.
Transform Streams: Modify data while reading or writing.
o Asynchronous JavaScript ?
JavaScript is a synchronous, blocking, single-threaded language
This nature however is not beneficial for writing apps
Asynchronous behaviour which is made possible by a browser for FE
and Node.js for backend
o Asynchronous nature of Node JS
Due to its asynchronous nature, long-running tasks (such as reading files or
making network requests) are handled in the background, allowing the main
thread to continue executing other code without waiting for the task to finish.
Non-blocking IO Model
This is why we use so many callback functions in NODE JS
Callback does not mean asynchronous
o differences between I/O operations and asynchronous programming ?
I/O Operations
Definition: Involves reading from or writing to external
sources (like files, databases, or networks).
Types:
Blocking I/O: The program waits for the I/O operation
to complete before proceeding.
Non-Blocking I/O: The program initiates the I/O
operation and can continue executing other code
without waiting for it to finish
Asynchronous Programming
Definition: A programming paradigm that allows tasks to be
executed without blocking the main flow of execution.
Nature: Always non-blocking, enabling the program to handle
multiple tasks concurrently.
Summary
I/O Operations: Can be either blocking or non-blocking.
Asynchronous Programming: Always emphasizes non-
blocking behavior.
Aspect I/O Operations Asynchronous Programming
Operations involving reading A programming paradigm that
from or writing to external allows tasks to run independently of
Definition
resources (e.g., files, the main flow, enabling non-
databases) blocking behavior
- Blocking I/O- Non- - Callbacks- Promises-
Types
blocking I/O Async/Await
Specifically about data input Managing task execution order and
Focus
and output flow
Can be synchronous
Generally emphasizes non-blocking
Nature (blocking) or asynchronous
execution
(non-blocking)
- Making a network request without
- Reading a file- Sending a
Examples halting execution- Using timers
request to a server
while allowing other code to run
Includes I/O tasks and other
Primarily involves tasks that
Application operations like computations or
read/write data
timers
o Binary data
0s and 1s that computers can understand.
Conversion: Turns all kinds of data (like text, images, numbers) into
combinations of 0s and 1s.
Purpose: This format is used inside the computer so that it can
understand and process the information.
Example: The letter "A" becomes 01000001 in binary
o Character set
Predefined lists of character represented by numbers.
Character Code Point
A 65
B 66
C 67
1 49
! 33
o Character encoding
Dictates how to represent a number in a character set as binary data.
Purpose: The primary purpose of character encoding is to convert characters
(letters, numbers, symbols) into a format that computers can understand,
which is binary data (composed of 0s and 1s).
Events
o Events, Event Emitter, Event Queue, Event Loop, & Event Driven in
Node.js?
Event: A signal that something has happened in a program (e.g., user
interactions, file operations).
Event Emitter: An object that allows you to create and emit events. It
can also listen for events and trigger specific actions when those events
occur.
Event Queue: A queue where emitted events are stored until
they are processed. This ensures that events are handled in the
order they were emitted.
Event Loop: A continuous loop that checks the call stack and event
queue. It picks up events from the event queue and executes their
associated callbacks in the order they were added, ensuring that the
application remains responsive.
Event-Driven: This approach allows the application to respond to
events as they happen, making it efficient for handling I/O operations
and improving scalability.
Event-driven architecture (EDA): it means operation in node are
drive or based by events.
o Event loop and Libuv ?
Event Loop: Manages asynchronous operations and callbacks,
ensuring Node.js remains non-blocking by checking the event queue
and the call stack.
Libuv: Provides the underlying library that enables asynchronous I/O
and manages the thread pool for blocking operations.
o NODE’S event loop ?
The event loop allows Node.js to handle many connections or requests
simultaneously in a non-blocking way, making it ideal for building highly
scalable applications, especially in real-time systems like chats, notifications,
and APIs
Single threaded
Supports concurrency via events & callbacks
EventEmitter class is used to bind events and listeners
o REPL
REPL(Read Eval Print Loop)
1. Read: The REPL reads the user's input command.
2. Eval: It evaluates (executes) the command.
3. Print: It prints the result of the execution.
4. Loop: The process loops back to the start, allowing the user to enter
more commands.
Example:
$ node
> 2 + 2
4
> console.log("Hello, World!");
Hello, World!
undefined
Advantages of REPL:
Quick Testing: You can quickly test code snippets without
needing to create a full program.
Learning Tool: It’s useful for beginners to experiment with
JavaScript syntax and Node.js features interactivel
o Overview of how a website works
TCP/IP
TCP/IP (Transmission Control Protocol/Internet Protocol) is a set of
rules that allows computers to communicate over a network like the
internet. It breaks data into smaller pieces (packets), sends them over
the network, and then reassembles them at the destination.
TCP: When loading a webpage, TCP ensures all parts of the
page (text, images) arrive correctly.
IP: IP addresses help route the data from your computer to the
website's server and back.
IP (Internet Protocol):
Handles Addressing: It assigns IP addresses to devices
and ensures that data packets are routed correctly across
the network to reach the intended destination.
Focuses on Routing: IP takes care of how packets
travel through different networks.
TCP (Transmission Control Protocol):
Handles Delivery: It ensures that the data packets are
delivered reliably and in the correct order.
Focuses on Reliability: TCP checks for errors,
retransmits lost packets, and guarantees that data arrives
intact and in the right sequence.
o UTF - 8
UTF-8 is like a universal translator for computers to read and show all
kinds of text.
UTF-8 is a way for computers to represent text.
It helps computers understand letters, symbols, and emojis from
different languages.
o Using events
1. Import the Events Module: First, you need to import the events
module and create an instance of the EventEmitter class.
2. Create Event Listeners: You can set up functions (listeners) that
respond when specific events occur.
3. Emit Events: You can trigger events using the emit() method.
o const EventEmitter = require('events'); // Import the events
module
o
o const myEmitter = new EventEmitter(); // Create an instance of
EventEmitter
o
o // Set up an event listener for the 'greet' event
o myEmitter.on('greet', () => {
o console.log('Hello! An event has occurred!');
o });
o
o // Emit the 'greet' event
o myEmitter.emit('greet'); // This will trigger the listener and
log the message
o
Routing - Router
o Routing
Routing defines the way in which the clint requests are handled by the
application endpoints.
We can our application to respond to different URLs with different
responses using Routing.
Routing basically means implementing different actions for different
URLs
o Routing in Node.js is done using the built-in http module and requires
manual checking of request URLs.
o
o const http = require('http');
o
o const server = http.createServer((req, res) => {
o if (req.url === '/') {
o res.writeHead(200, {'Content-Type': 'text/plain'});
o res.end('Home'); // Home page response
o } else {
o res.writeHead(404);
o res.end('Not Found'); // 404 response
o }
o });
o
o server.listen(3000, () => {
o console.log('Server running on <http://localhost:3000>');
o });
o Routing in Express provides a cleaner, more intuitive way to define routes,
making it easier to manage web applications.
o const express = require('express');
o const app = express();
o
o app.get('/', (req, res) => {
o res.send('Home'); // Home page response
o });
o
o app.use((req, res) => {
o res.status(404).send('Not Found'); // 404 response
o });
o
o app.listen(3000, () => {
o console.log('Server running on <http://localhost:3000>');
o });
o
o Routing vs Router
Routing
Routing is the overall concept of handling requests to different URLs.
app.get('/', (req, res) => {
res.send('Home Page');
});
Router
A router is a tool in Express to help organize related routes, making
the code easier to manage.
const express = require('express');
const router = express.Router();
router.get('/login', (req, res) => {
res.send('Login Page');
});
router.get('/register', (req, res) => {
res.send('Register Page');
});
module.exports = router; // Exporting the router for use
in the main app
o Router Chaining
Router Chaining is a way of organizing multiple routes under a single route
path using the express.Router instance. This allows you to chain multiple
HTTP methods (like GET, POST, PUT, DELETE) or middleware for a
common base path in a cleaner and more readable way.
Why Use Router Chaining?
Organized Code: Group all related routes for a resource under a single
router.
Avoid Repetition: Avoid repeating the same base path for multiple
routes.
Logical Structure: Helps to maintain a modular route structure.
How Router Chaining Works
4. Create an express.Router instance.
5. Define multiple routes (or methods) using .get(), .post(), .put(),
.delete(), etc.
6. Attach the router to a specific base path using app.use().
const express = require('express');
const app = express();
const router = express.Router(); // Create a router instance
// Chain multiple routes for a single resource (e.g.,
/products)
router
.get('/', (req, res) => {
res.send('List of all products');
})
.post('/', (req, res) => {
res.send('Create a new product');
})
.put('/:id', (req, res) => {
res.send(`Update product with ID: ${req.params.id}`);
})
.delete('/:id', (req, res) => {
res.send(`Delete product with ID: ${req.params.id}`);
});
// Attach the router to the base path
app.use('/products', router);
// Start the server
app.listen(3000, () => {
console.log('Server is running on <http://localhost:3000>');
});
o Dynamic Routing
Routes that include parameters or respond dynamically to input.
app.get('/user/:id', (req, res) => {
res.send(`User ID: ${req.params.id}`);
});
Clustering vs Thread Pool
o Clustering ?
Clustering in Node.js improves performance by using multiple CPU
cores.
By default, Node.js runs on a single thread, using only one CPU core.
Clustering creates multiple child processes (called workers) to share
the workload.
Workers handle requests, helping the app manage many users at once.
This allows for better CPU utilization and faster handling of
concurrent requests.
Each child process (worker) can run on a different CPU core.
These child processes share the same port but handle requests
independently.
Child process
A child process in Node.js refers to a separate execution
context created by the main (or parent) process to perform
tasks. This allows Node.js to run multiple processes
concurrently, enabling better performance and utilization of
system resources, especially on multi-core systems.
o Thread pool
Node.js handles many tasks using a single main thread.
Blocking operations (like reading files) can slow everything down.
A thread pool is a group of helpers that can work on these long tasks.
When a blocking task happens, it’s sent to the thread pool.
The main thread continues to work on other tasks while the helpers
finish the long task.
This keeps the application fast and responsive.
o Tread pool vs Cluster
Feature Thread Pool Clustering
A group of threads managed A method to create multiple
Definition by Node.js for handling child processes that can utilize
blocking operations. multiple CPU cores.
To perform I/O-bound tasks
To improve performance by
(like file reading/writing)
Purpose enabling parallel handling of
without blocking the main
requests across multiple cores.
event loop.
Manages blocking
Distributes incoming requests
operations in the same
Functionality across multiple processes, each
process, keeping the event
with its own event loop.
loop responsive.
Usage Used for tasks that can take Used when you want to scale
time, like database queries your application horizontally
Feature Thread Pool Clustering
or file operations. across CPU cores.
Built-in mechanism in Achieved through the cluster
Implementation Node.js (using the libuvmodule in Node.js, which forks
library) to handle I/O tasks.
child processes.
Limited to a fixed number
Can scale horizontally as
Scalability of threads (default is 4) but
needed, limited only by system
can be adjusted. resources.
Child processes have separate
Threads share memory and
memory spaces; communication
Communication can communicate through
is done via IPC (Inter-Process
shared variables.
Communication).
Cookies ? Session ? JWT
o Cookies ?
Cookies are small pieces of data stored on the client’s browser, used for
remembering information across multiple requests or sessions.
Scope: Can be accessed by both the server and client.
Lifetime: Can persist for a session or a set time (expiry).
Size: Limited to around 4 KB.
Use Cases: Used for session management, user tracking, and
authentication.
Security: Can be secured using flags like HttpOnly and Secure.
o Session ?
In Node.js with Express, a session stores user data (like login info) across
multiple requests. The data stays on the server, and a session ID in a cookie is
sent to the client, helping the server recognize users.
The server stores the following in the session
"userID": 12345, "username": "johndoe", "email": "[email protected]",
"isLoggedIn": true, "theme": "dark", "language": "English", "cart": []
Middleware: express-session is commonly used. Use Case: Sessions keep
users logged in and store preferences across pages.
Example
const express = require('express');
const session = require('express-session');
const app = express();
const port = 3000;
// Set up session middleware
app.use(session({
secret: 'mySecretKey', // Secret key to sign session
ID cookie
resave: false, // Avoid saving session if not
modified
saveUninitialized: true // Save uninitialized sessions
}));
// Route to set a session value
app.get('/set-session', (req, res) => {
req.session.user = 'John Doe'; // Store user in
session
res.send('Session set');
});
// Route to get session value
app.get('/get-session', (req, res) => {
const user = req.session.user || 'Guest'; // Get
session data
res.send(`Hello, ${user}`);
});
app.listen(port, () => {
console.log(`Server running on <http://localhost>:$
{port}`);
});
o JWT
JWT (JSON Web Token) is a secure way to share information between two
parties, like a client and a server. It's often used in web applications for user
authentication and authorization.
Summary of How JWT Works:
1. Login: User logs in, server creates a token.
2. Store Token: Client stores the token and uses it for future
requests.
3. Send Token in Requests: Token is included in headers to
prove identity.
4. Verify Token on Server: Server checks token’s authenticity
and expiration.
5. Access Control: Valid tokens get access, invalid tokens are
denied.
When you log in, the server creates a token (JWT) containing your
details, signs it, and sends it to you.
You send this token with every request to prove you’re allowed to
access certain parts of the app.
The token is divided into three parts: header (info on the token type),
payload (your details), and a signature (to ensure it hasn't been
changed).
Storage Location: JWTs are stored on the client (often in browser
storage or in the request header).
Statefulness: Stateless because all the necessary data is encoded
inside the token itself, and no server storage is required.
Data Security: JWTs are encoded and can be decoded. While they can
be secured with a secret key (signed), the data within the token is
visible.
Expiration: JWTs have an expiration time embedded in the token
itself.
Usage: JWTs are commonly used in APIs, single-page apps, or
services where stateless authentication is preferred.
Example Use Case: Authenticating API calls without requiring server-
side storage.
o Session ID and uuidv4 in Simple Terms
uuidv4() is only used on the server to sign and secure the session.
The session ID (not uuidv4) is sent to the user's browser in a cookie.
How it works:
1. Server-side:
The uuidv4() generates a unique secret key, and this
secret is stored securely on the server.
When the server creates a session, it signs the session
data (including the session ID) using the secret key.
2. Browser-side:
The user's browser only receives the session ID in the
form of a cookie. The actual secret generated by
uuidv4() never leaves the server.
3. Verification:
Each time the browser sends the session ID back to the
server (when making requests), the server checks if it’s
valid by verifying it with the secret key created by
uuidv4().
This ensures the session hasn’t been tampered with by
anyone on the client side.(The line means that the server
can confirm that the session data hasn't been changed by
anyone trying to cheat the system, keeping the user’s
session secure.)
Example
uuidv4() generates something like this on the server:
d4a7dcb7-bf54-4c9b-9fd2-2e5d8b656d31.
The user receives a session ID like abc123 as a cookie.
The secret (uuidv4) stays on the server, ensuring the session
cookie is secure.
JWT (JSON Web
Feature Cookies Sessions
Token)
Storage Stored in the browser Stored on the client (e.g.,
Stored on the server
Location (client-side) browser storage)
Stateless by Stateful (session data Stateless (no server
Statefulness
themselves is on the server) storage needed)
Data is secure on the Data is included in the
Data Security Limited data stored
server token (can be decoded)
Set by expiration date Managed by server Set by token expiration
Expiration
in the browser session timeout time
Stores user
Stores user data for Often used for APIs and
Usage preferences or session
logged-in sessions single-page apps
ID
Example Use Remember login Keep user logged in Authenticate API calls
JWT (JSON Web
Feature Cookies Sessions
Token)
Case preferences on the server without server storage
Other relative contents
o CORS & CSRF
CORS (Cross-Origin Resource Sharing) ?
CORS (Cross-Origin Resource Sharing) is a security feature in
browsers. It stops websites from making requests to different websites
to protect your information. By default, if one website tries to request
data from another site, the browser blocks it.
CORS allows websites to make these requests safely if the other site
explicitly allows it, preventing harmful sites from accessing sensitive
data on your browser.
In CORS (Cross-Origin Resource Sharing), your website (frontend)
is making a request to another website or server (which is on a
different domain or origin).
Setting Up CORS in Node.js
To enable CORS in your Node.js application, you can use the
cors middleware package.
Steps
1. Install the cors package:
2. npm install cors
3. Use the cors middleware in your app:
4. const express = require('express');
5. const cors = require('cors');
6. const app = express();
7.
8. // Enable CORS for all routes
9. app.use(cors());
10.
11. // Define routes
12. app.get('/', (req, res) => {
13. res.send('CORS is enabled for all
routes!');
14. });
15.
16. // Start the server
17. const PORT = 3000;
18. app.listen(PORT, () => {
19. console.log(`Server is running on port $
{PORT}`);
20. });
21. Configuring CORS (Optional): You can specify
specific origins, methods, and headers for more control.
For example:
22. const corsOptions = {
23. origin: '<https://example.com>', // Allow
only this origin
24. methods: ['GET', 'POST'], // Allow only
GET and POST methods
25. allowedHeaders: ['Content-Type',
'Authorization'], // Allow only these headers
26. };
27.
28. app.use(cors(corsOptions));
29. Finally code look like this
30. const express = require('express');
31. const cors = require('cors');
32. const app = express();
33.
34. // Define CORS options
35. const corsOptions = {
36. origin: '<https://example.com>', // Allow
only this domain
37. methods: ['GET', 'POST'], // Allow only
these HTTP methods
38. allowedHeaders: ['Content-Type',
'Authorization'], // Allow only these headers
39. };
40.
41. // Use CORS middleware with options
42. app.use(cors(corsOptions));
43.
44. // Define routes
45. app.get('/', (req, res) => {
46. res.send('CORS is enabled with specific
options!');
47. });
48.
49. // Start the server
50. const PORT = 3000;
51. app.listen(PORT, () => {
52. console.log(`Server is running on port $
{PORT}`);
53. });
54.
Explanation
Origin: Specifies the domain that is allowed to access
the server's resources.
Methods: Specifies HTTP methods allowed (e.g., GET,
POST, DELETE).
Allowed Headers: Specifies which headers the client
can include in requests.
Enabling CORS is essential when building APIs that may be
accessed from different domains, such as front-end applications
hosted separately from your back-end server.
CSRF (Cross-Site Request Forgery) ?
CSRF (Cross-Site Request Forgery) is a type of attack where a
malicious website tricks a user’s browser into making unwanted
requests to another website where the user is authenticated. This can
result in unauthorized actions being performed without the user's
knowledge.
CSRF (Cross-Site Request Forgery) is an attack where a
malicious website can make a request on behalf of an
authenticated user to another site.
CSRF tokens are a common method to prevent these attacks
by ensuring that the request is coming from the actual user.
SameSite Cookies provide an additional layer of defense by
restricting when cookies are sent with requests.
Always verify requests by checking tokens and HTTP headers
to protect your users from CSRF attacks.
o Preflight Request
When a website tries to access resources from another origin (like a different
domain), it first sends a preflight request to the server. This request is
typically an OPTIONS request. The server then responds with an HTTP status
code indicating whether the actual request is allowed or not.
Explanation
1.What Happens:
When a website wants to get information from another
website (different domain), it first sends a preflight
request to check if it’s allowed. This is done using an
OPTIONS request.
2. Server Response:
The server replies with a status code:
200 OK or 204 No Content means the actual
request is allowed.
403 Forbidden or 401 Unauthorized means the
request is not allowed.
3. Why It Matters:
This process keeps cross-origin requests safe and lets
the server control what can be accessed from other
domains.
o CORS and Preflight Requests
CORS (Cross-Origin Resource Sharing) is a security feature
implemented by browsers to control how web pages can request
resources from different origins (domains).
A preflight request is part of the CORS mechanism. It is sent by the
browser before the actual request to check if the server allows the
cross-origin request.
The server responds to the preflight request with HTTP status codes
and headers that indicate whether the actual request is permitted.
o Content-Type
Content-Type tells the server what type of data the client is sending or
expects to receive.
Purpose of Content-Type
In Requests: When a client (like a browser or app) sends data to a
server, Content-Type tells the server what format the data is in (e.g.,
JSON, plain text).
In Responses: When a server sends data back to the client, it uses
Content-Type to let the client know how to interpret the response.
o cores & threads
Cores: Parts of the CPU that do the work. More cores = more things
done at the same time.
Threads: Tiny tasks for the cores. Cores can switch between them
fast, making it seem like they’re doing many things at once.
o Same Origin Policy (SOP)
Definition: SOP is a security rule in web browsers that prevents a
webpage from accessing data from a different website (origin) unless
they are from the same origin (same protocol, domain, and port).
Purpose: It protects user data by stopping harmful scripts on one
website from interacting with another website's data.
Simple Example:
3. Same Origin:
A script on https://example.com can access resources on
https://example.com/data.
4. Different Origin:
A script on https://example.com cannot access resources on
https://another-example.com/data.
o SOP - CORS - Preflight request (preflight call)
SOP protects against unauthorized access to data.
CORS allows specific cross-origin requests.
Preflight Requests are used to check permissions before sending
sensitive requests.
o JSON parsing and stringifying
JSON (JavaScript Object Notation) is a format for storing and exchanging
data. It's simple, uses key-value pairs, and is easy for both people and
computers to understand.
Uses of JSON:
1. Data Exchange: Helps send data between a server and a web
application.
2. Configuration Files: Used for settings in applications.
3. Data Storage: Stores data in a structured, readable way in
databases.
4. Serialization: Converts data into text for easy storage or
transfer, then back into its original form.
JSON Parsing (JSON.parse()):Converts a JSON-formatted string
into a JavaScript object
Useful when receiving JSON data from an API or file and you
need to work with it as an object.
Example:
const jsonString = '{"name": "Alice", "age": 25}';
const jsonObject = JSON.parse(jsonString);
console.log(jsonObject.name); // Output: Alice
JSON Stringifying (JSON.stringify()):Converts a JavaScript object
into a JSON-formatted string.
Useful when sending data as JSON, like in an HTTP request, or
saving to a file.
Example:
const jsonObject = { name: "Alice", age: 25 };
const jsonString = JSON.stringify(jsonObject);
console.log(jsonString); // Output:
'{"name":"Alice","age":25}'
o BSON (Binary JSON)
BSON (Binary JSON) is a binary representation of JSON-like documents. It
is used primarily in MongoDB and other applications where performance and
efficiency in data storage and transfer are important.
o Scaffolding (project structure)
scaffolding refers to the automated creation of the basic structure or layout of
a project. It sets up files, folders, and code templates according to best
practices, giving developers a starting point and helping them organize their
code effectively.
Common Scaffolding Layout in Web Development
project-name/
│
├── public/ # For static assets (CSS, JS, images)
│
├── src/
│ ├── routes/ # For app routes
│ ├── controllers/ # For app logic
│ ├── models/ # For database models
│ ├── views/ # For HTML templates
│ └── app.js # Main app entry point
│
└── package.json # Project metadata and dependencies
o Blocking code
Blocking code in programming is any code that stops further execution until a
specific operation completes. This type of code holds up the entire program,
preventing other tasks from running. In the context of Node.js, which is
designed to handle many tasks concurrently, blocking code can reduce
performance since it prevents other operations from continuing until the
current task finishes.
o Conditional operator vs. optional chaining
Conditional operator or ternary operator**(? :)**
Used to evaluate a condition and return one of two values based
on that condition.
Syntax: condition ? valueIfTrue : valueIfFalse
It’s an alternative to if-else for simple conditions.
Example:
const age = 20;
const isAdult = age >= 18 ? 'Yes' : 'No';
console.log(isAdult); // Output: "Yes"
Optional chaining (?.)
Used to safely access nested object properties without throwing
an error if a reference is null or undefined.
Syntax: object?.property?.subProperty
Prevents runtime errors by returning undefined if a property in
the chain is missing, instead of throwing an error.
Example:
const user = { name: 'Alice', address: { city:
'Wonderland' } };
console.log(user?.address?.city); // Output:
"Wonderland"
console.log(user?.contact?.phone); // Output:
undefined (instead of an error)
o Why Node.js uses a single thread
Node.js uses a single thread to keep things simple and efficient. It relies on
non-blocking operations and an event loop to handle multiple tasks, which
allows it to manage lots of requests at once without needing extra threads. This
keeps the code simpler and helps prevent errors that come with managing
multiple threads.
o Thread pool
Node.js handles many tasks using a single main thread.
Blocking operations (like reading files) can slow everything down.
A thread pool is a group of helpers that can work on these long tasks.
When a blocking task happens, it’s sent to the thread pool.
The main thread continues to work on other tasks while the helpers
finish the long task.
This keeps the application fast and responsive.
Additional Modules and Tools
o LOCALSTORAGE/SESSIONSTORAGE
Feature LocalStorage SessionStorage
Shared across all tabs/windows of Only available in the current
Scope
the same origin. tab/window.
Data persists even after the Data is cleared when the
Lifetime
browser is closed and reopened. tab/window is closed.
Storage
Typically around 5-10 MB. Typically around 5-10 MB.
Limit
For long-term storage of data (e.g., For temporary storage of data
Use Case
user settings). (e.g., session data).
Accessible by JavaScript on the Accessible by JavaScript on
Access
client-side. the client-side.
o Query Parameters ?
Query parameters are key-value pairs that appear at the end of a URL,
allowing data to be sent to the server as part of the URL itself. They are
typically used in web development to pass additional information in requests,
such as specifying search terms, filters, page numbers, or other variables.
Query parameters are added after a ? in the URL.
Key-value pairs format: key=value.
Multiple parameters are separated by &.
eg:https://example.com/search?query=nodejs&limit=10
o Query parameters and path parameters
Query Parameters:
Found at the end of a URL, after a ?.
Represented as key-value pairs, separated by &.
Used for filtering, sorting, or searching.
Example: https://example.com/products?
category=books&sort=price
Path Parameters:
Embedded directly within the URL path.
Often identify specific resources.
Example: https://example.com/products/123 (where 123
is the product ID).
Query parameters are for optional data, often for filtering or
searching.
Path parameters identify specific resources in the URL path.
Concept Explanation Example
Key-value pairs
Query added after ? in the /products?category=books&sort=price
Parameter URL, used for
filtering or searching.
Identifies specific
Path /products/123 (where 123 is a product
resources directly in
Parameter ID)
the URL path.
o Encryption / Hashing
Encryption transforms data into a coded format, which can be
reversed (decrypted) using a key. Turns readable data into unreadable
cipher text.
Decryption turns the unreadable cipher text back into readable data.
Hashing converts data into a fixed-size string of characters, which
cannot be reversed, typically used for securing passwords.
o Authorization / Authentication
Authentication is the process of verifying the identity of a user or system
(e.g., checking login credentials like username and password).
Authorization is the process of determining whether an authenticated user has
the right to access specific resources or perform actions (e.g., access control
based on roles).
In short, Authentication asks "Who are you?" and Authorization asks "What
can you do?"
o I/O Operations:
I/O operations (Input/Output operations) are tasks that involve getting data
from or sending data to something outside the computer, like reading a file,
sending a request over the internet, or getting input from a user.
Examples of I/O operations:
Reading files from your computer.
Sending/receiving data over the internet (like a webpage loading).
Taking user input, like typing on a keyboard.
Saving data to a database.
o Process.nextTick ?
process.nextTick() schedules a callback function to be executed
immediately after the current operation completes, but before any I/O
operations or timers are processed.
console.log('Start');
process.nextTick(() => {
console.log('This runs first in nextTick');
});
console.log('End');
o setImmediate() ?
setImmediate() schedules the callback to run after the current event loop
iteration, but before any timers or I/O events in the next cycle.
It doesn’t wait for all I/O operations or timers that were scheduled in the
current phase to complete.
console.log('Start');
process.nextTick(() => {
console.log('This runs in nextTick');
});
setImmediate(() => {
console.log('This runs in setImmediate');
});
console.log('End');
// Expected Output:
// Start
// End
// This runs in nextTick
// This runs in setImmediate
o Process.nextTick vs setImmediate() vs setTimeout()
Example
console.log('Start');
process.nextTick(() => {
console.log('This runs in process.nextTick()');
});
setImmediate(() => {
console.log('This runs in setImmediate()');
});
setTimeout(() => {
console.log('This runs in setTimeout()');
}, 0);
console.log('End');
// Answers-------------------------------------------
// Start
// End
// This runs in process.nextTick()
// This runs in setImmediate()
// This runs in setTimeout()
When It
Method Use Case Priority
Runs
After the Defer
current execution Highest - executes before
process.nextTick() operation, within the setImmediate() and
before any same event setTimeout()
I/O loop
After the Run after
setImmediate()
current event current Medium - runs after
loop cycle operations, process.nextTick()
completes before I/O
After the
Run after a
specified
delay, with Lowest - waits for the
setTimeout() delay, in the
the specified specified delay
next event
time
loop
o Read/write operations
Read Operation: Retrieves data without changing it.
Example: Reading a file, querying a database to get user info.
In code, this might look like:
fs.readFile('data.txt', (err, data) => {
if (err) throw err;
console.log(data);
});
Write Operation: Adds or changes data.
Example: Writing to a file, updating a database record.
In code, this might look like:
fs.writeFile('data.txt', 'Hello World', (err) => {
if (err) throw err;
console.log('Data written!');
});
o Request and response headers ?
Request Headers
Accept: Specifies the media types that the client can process
(e.g., Accept: application/json).
Authorization: Contains credentials for authenticating the
client (e.g., Authorization: Bearer token).
Content-Type: Indicates the media type of the resource being
sent (e.g., Content-Type: application/json).
User-Agent: Provides information about the client software
(e.g., User-Agent: Mozilla/5.0).
Cookie: Contains stored cookies from the client (e.g., Cookie:
sessionId=abc123).
Response Headers
Content-Type: Indicates the media type of the resource being
returned (e.g., Content-Type: application/json).
Cache-Control: Directives for caching mechanisms (e.g.,
Cache-Control: no-cache).
Set-Cookie: Sends cookies from the server to the client (e.g.,
Set-Cookie: sessionId=abc123).
Location: Used in redirection, specifies the URL to redirect
the client to (e.g., Location: <https://example.com>).
Server: Contains information about the server software (e.g.,
Server: Apache/2.4.1).
Request Headers: Sent by the client to provide context about the
request.
Response Headers: Sent by the server to convey information about the
response.
o Dev dependencies vs. dependencies
Dependencies are essential for your application to run in production.
DevDependencies are only necessary during development and testing.
o DNS module
The dns module in Node.js provides functions to interact with the Domain
Name System (DNS), which is how domain names (like example.com) are
translated to IP addresses. This module lets Node.js apps perform DNS
lookups and resolve domain names programmatically.
DNS helps turn website names (like amazon.com) into IP addresses so
your computer can find them.
If a website’s address is not in your computer's cache, it will ask a
DNS server to find it.
If Google’s DNS doesn’t have it, it asks the authoritative server, which
always has the correct IP address.
o .env vs dotenv vs process.env
.env (File)
This is a file where you store environment variables (key-
value pairs) that you don’t want to hard-code in your code.
Keeps sensitive info private: It hides your passwords and API
keys from the public.
Works in different environments: You can use different
settings for development and production without changing your
code.
Easy to update: You can update values without changing your
code.
When you use a .env file in GitHub (or any Git repository), it
helps by keeping sensitive information (like API keys,
passwords) out of your code, so you don’t accidentally expose
them.
It looks like this:
PORT=3000
DATABASE_URL=mongodb://localhost:27017/myap
2. dotenv (Package)
dotenv is a Node.js package that reads the .env file and
makes the variables inside it available to your code.
You need to install it and use it in your application to load the
.env variables.
3. process.env (Object)
is a built-in object in Node.js that holds all the
process.env
environment variables.
Once dotenv loads the variables from .env, you access them
through process.env.
How They Work Together:
3. You create a .env file with environment variables.
4. You use the dotenv package to load the .env file into your
application.
5. You access the values in your application using process.env.
Example:
6. .env File:
7. PORT=3000
8. DATABASE_URL=mongodb://localhost:27017/myapp
9. Install dotenv Package:
10. npm install dotenv
11. In Your Code:
12. // Load the .env variables
13. require('dotenv').config();
14.
15. // Access them using process.env
16. const port = process.env.PORT; // 3000
17. const dbUrl = process.env.DATABASE_URL; //
mongodb://localhost:27017/myapp
18.
19. console.log(port); // Outputs: 3000
20. console.log(dbUrl); // Outputs:
mongodb://localhost:27017/myapp
Summary:
.env: File where you store your variables.
dotenv: Package that loads variables from .env into your app.
process.env: The object where you access these variables in your
code.
Another topics
o Params
Params (Route Parameters):
Params: Used to capture dynamic values in the URL path.
What It Is: Values in the URL that you define in your route.
Purpose: To capture dynamic information from the URL.
Example: In the route /users/:userId, :userId is a
parameter.
How It Works: If a user visits /users/123, the userId would
be 123.
Accessing It: You can get the value using req.params in
Express:
app.get('/users/:userId', (req, res) => {
const userId = req.params.userId; // This will
be '123'
res.send(`User ID is: ${userId}`);
});
o Query parameter
Definition: Query parameters are used to send additional information
in the URL to the server. They appear after a ? and are separated by &.
Structure:
Example: http://example.com/page?
key1=value1&key2=value2
Here, key1 and key2 are parameter names, while value1 and
value2 are their respective values.
Usage in Express:
You can access query parameters using req.query in an
Express route.
Example:
app.get('/search', (req, res) => {
const searchTerm = req.query.term; // Example: ?
term=apple
const page = req.query.page; // Example: ?page=2
res.send(`Search term is: ${searchTerm}, Page number
is: ${page}`);
});
test
- Run your Express server.
- Access the URL, e.g., `http://localhost:3000/search?
term=apple&page=2`, in your browser or API tool.
Expected Output:
The response will show the captured values: Search
term is: apple, Page number is: 2.
o Libuv
Definition: A multi-platform support library used by Node.js to handle
asynchronous I/O operations. It provides an event-driven architecture
and supports features like networking, file system, and child processes.
Purpose: It abstracts system-specific functionalities (like
asynchronous I/O) across different operating systems (Linux,
Windows, macOS).
o Params - Query - Libvuv
Params: Used to capture dynamic values in the URL path.
Query: Used to send additional data in the URL, typically for filtering
or sorting.
libuv: A library that Node.js uses for non-blocking I/O operations,
making it possible to handle multiple connections simultaneously
without blocking.
o Control flow
Definition: Control flow is the order in which statements or instructions are
executed in a program, guiding how the program responds to conditions and
loops.
Components:
Sequential Execution: Code runs line by line.
Conditional Statements: if, else, switch for decision-making.
Loops: for, while for repeating code blocks.
Function Calls: Executing defined blocks of code.
Example:
const score = 85;
if (score >= 90) {
console.log('Grade: A');
} else if (score >= 80) {
console.log('Grade: B');
} else {
console.log('Grade: C');
}
Purpose: Control flow determines program behavior based on user input and
data states.
o Work flow
Definition: Workflow is the sequence of processes followed to complete a
task or achieve a goal, often involving multiple tasks and collaboration.
Components:
Tasks: Individual work units.
Sequence: Order of task execution.
Dependencies: Relationships between tasks.
Participants: Individuals or systems involved.
Example: In an order processing workflow:
4. Receive Order: Customer places an order.
5. Validate Order: Check order details.
6. Process Payment: Handle payment.
7. Ship Order: Send order to the customer.
8. Notify Customer: Inform the customer of shipment.
Purpose: Workflows manage complex processes, ensuring efficiency and
clarity in execution
o Control flow - Work flow
Aspect Control Flow Workflow
Focuses on execution order in Focuses on broader processes and
Scope
code tasks
High-level (organizational
Level Low-level (code execution)
processes)
Components Statements, conditions, loops Tasks, sequences, dependencies
Purpose Determine program behavior Manage complex processes
o Summary
Control flow is about how individual pieces of code are executed
based on conditions, loops, and branching logic.
Workflow is about the overall process and sequence of tasks needed to
complete a larger goal or objective within an organization or system.
o Dependencies - DevDependencies
Dependencies
Purpose: Used to run the application in production.
Example: Frameworks and libraries like Express or Axios.
DevDependencies
Purpose: Used for development tasks, testing, and building the
application.
Example: Testing frameworks like Jest or development tools
like ESLint.
o Error-First Callbacks
Definition: In Node.js, an error-first callback is a way to handle errors in
asynchronous functions. The first parameter of the callback is an error (if there
is one), and the rest are the results.
Simple Example:
const fs = require('fs');
// Read a file using an error-first callback
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error:', err); // Log the error if
it occurs
return; // Stop the function if there's an error
}
console.log('File content:', data); // Log the file
content if successful
});
o Socket
A socket is a communication endpoint that allows two devices (which
could be a client and a server, or any two devices on a network) to send
and receive messages.
Sockets can use different protocols like TCP or UDP to manage how
data is exchanged.
Used for general network communication, like:
File transfers
Messaging between devices or applications
Network services
In short, a socket creates a connection between two devices, enabling them to
send and receive data.
o WebSocket
WebSocket is a protocol used for two-way communication
specifically between a client (like a web browser) and a server.
It is designed for real-time data exchange, keeping the connection
open so both the client and server can send messages to each other
without repeatedly reconnecting.
Used for applications like:
Chat apps
Live notifications
Online gaming
WebSocket specifically refers to two-way communication between a
client (like a web browser) and a server.
A Socket can be used for two-way communication between any two
devices on a network, not just a client and server.
o Reactor Pattern
The Reactor Pattern is a design pattern used in event-driven programming to
handle multiple input/output (I/O) operations efficiently. It enables a single
thread to manage multiple tasks concurrently by delegating work and reacting
to events as they occur.
0. Event Demultiplexer:
Watches multiple sources (e.g., HTTP requests, file operations) for
new events and passes them to the reactor.
1. Reactor (Event Loop):
Continuously checks for events from the demultiplexer and sends them
to the appropriate handler.
2. Handlers (Callbacks):
Functions that process specific events when the reactor signals them.
o PM2
PM2 is a popular, production-grade process manager for Node.js applications.
It helps you manage and keep your Node.js apps alive forever, providing
features for process monitoring, load balancing, and error handling. It’s widely
used to deploy and maintain Node.js applications in production environments.
CRYPTO Module
The crypto module in Node.js provides cryptographic functionality, including:
o Hashing: Converts data into a fixed-size string.
o Encryption/Decryption: Secures data by encoding and decoding it using
algorithms.
o Random Values: Generates secure random numbers or strings.
API 🌐
API (Application Program Interface) ?
An API (Application Programming Interface) is a set of protocols that allows different
software applications to communicate and interact with each other.
o PRACTICAL
Steps:
1. Install Express:
2. npm init -y
3. npm install express
4. Create a file called app.js:
const express = require('express');
const app = express();
const port = 3000;
app.get('/greet', (req, res) => {
res.send('Hello, this is a simple API!');
});
app.listen(port, () => {
console.log(`API is running on <http://localhost>:${port}`);
});
5. Run the server:
6. node app.js
Now, you can access the API at http://localhost:3000/greet
Why we use API 🌐 ?
o Data Sharing: Allow different apps to share data easily.
o Function Access: Provide access to features without needing to build them.
o System Integration: Help connect different systems and services.
o Save Time: Reduce development time by reusing existing services.
o Scalability: Enable applications to grow by adding new features easily.
o Security Control: Protect sensitive actions by controlling access.
Web API
Web API: A type of API specifically designed for web applications, allowing them to
interact over the internet using HTTP requests.
REST API (Representational State Transfer API) ?
A REST API is a way for different software to communicate over the internet using
standard web methods. It lets you do things like create, read, update, or delete data.
Key points:
1. Stateless: Each request is independent; the server doesn’t remember previous
requests.
2. Resource-Based: Each item (like a book) has a unique address (URL).
3. Uses HTTP Methods:
GET: Fetch data
POST: Add new data
PUT: Change existing data
DELETE: Remove data
o Diagram
o PRACTICAL
o const express = require('express'); // Import Express
o const app = express(); // Create app instance
o const port = 3000; // Set port
o
o app.use(express.json()); // Middleware to parse JSON
o
o // Sample data (items)
o let items = [
o { id: 1, name: 'Item 1' }, // Item 1
o { id: 2, name: 'Item 2' } // Item 2
o ];
o
o // GET: Fetch all items
o app.get('/api/items', (req, res) => {
o res.json(items); // Return all items
o });
o
o // GET: Fetch specific item by ID
o app.get('/api/items/:itemId', (req, res) => {
o const item = items.find(i => i.id ===
parseInt(req.params.itemId)); // Find item
o if (!item) return res.status(404).send('Not found'); // If
not found
o res.json(item); // Return item
o });
o
o // POST: Add new item
o app.post('/api/items', (req, res) => {
o const newItem = { id: items.length + 1, name:
req.body.name }; // Create new item
o items.push(newItem); // Add to array
o res.status(201).json(newItem); // Return new item
o });
o
o // PUT: Update item by ID
o app.put('/api/items/:itemId', (req, res) => {
o const item = items.find(i => i.id ===
parseInt(req.params.itemId)); // Find item
o if (!item) return res.status(404).send('Not found'); // If
not found
o item.name = req.body.name; // Update item name
o res.json(item); // Return updated item
o });
o
o // DELETE: Remove item by ID
o app.delete('/api/items/:itemId', (req, res) => {
o items = items.filter(i => i.id !==
parseInt(req.params.itemId)); // Remove item
o res.status(204).send(); // No content response
o });
o
o // Start server
o app.listen(port, () => {
o console.log(`Server running at <http://localhost>:$
{port}`); // Log server start
o });
Why we use REST API 🌐 ?
o Stateless: Each request is independent, making it easier to scale and manage.
o Standardized Protocols: Uses HTTP methods (GET, POST, PUT, DELETE)
that are widely understood.
o Resource-Based: Focuses on resources (like data) instead of actions, making
it more intuitive.
o Cacheable: Responses can be cached, improving performance.
o Uniform Interface: Simplifies interaction between clients and servers,
enhancing usability.
API vs REST API ?
Feature API 🌐 REST API 🌐
Type of API that follows REST
Interface that allows
Definition (Representational State Transfer)
software to communicate.
architecture.
Can use multiple protocols
Protocol Uses HTTP protocol specifically.
(e.g., SOAP, RPC).
Follows REST architecture principles
Architecture Varies, can be custom.
(stateless, resource-based).
Supports multiple formats Typically uses JSON or XML for data
Data Format
(e.g., XML, JSON). exchange.
State Always stateless; each request is
Can be stateful or stateless.
Management independent.
May or may not support
Caching Built-in support for HTTP caching.
caching.
For general communication Best for web services and client-server
Use Case
between systems. interactions.
REST API vs Web API vs SOP API?