FSD Unit I &II
FSD Unit I &II
Full Stack Development refers to the development of both front end (client side) and back
end (server side) portions of web applications.
full Stack Web Developers
Full Stack web developers have the ability to design complete web applications and websites. They
work on the frontend, backend, database, and debugging of web applications or websites.
Front-end Development
It is the visible part of website or web application which is responsible for user experience. The user
directly interacts with the front end portion of the web application or website.
Front-end Technologies
The front end portion is built by using some languages which are discussed below:
HTML: HTML stands for Hyper Text Markup Language. It is used to design the front end
portion of web pages using markup language. HTML is the combination of Hypertext and
Markup language. Hypertext defines the link between the web pages. The markup language
is used to define the text documentation within tag which defines the structure of web pages.
CSS: Cascading Style Sheets, fondly referred to as CSS, is a simply designed language
intended to simplify the process of making web pages presentable. CSS allows you to apply
styles to web pages. More importantly, CSS enables you to do this independent of the HTML
that makes up each web page.
JavaScript: JavaScript is a famous scripting language used to create the magic on the sites
to make the site interactive for the user. It is used to enhancing the functionality of a website
to running cool games and web-based software.
Front End Libraries and Frameworks
AngularJS: AngularJs is a JavaScript open source front-end framework that is mainly used
to develop single page web applications(SPAs). It is a continuously growing and expanding
framework which provides better ways for developing web applications. It changes the static
HTML to dynamic HTML. It is an open source project which can be freely used and
changed by anyone. It extends HTML attributes with Directives, and data is bound with
HTML.
React.js: React is a declarative, efficient, and flexible JavaScript library for building user
interfaces. ReactJS is an open-source, component-based front end library responsible only
for the view layer of the application. It is maintained by Facebook.
Bootstrap: Bootstrap is a free and open-source tool collection for creating responsive
websites and web applications. It is the most popular HTML, CSS, and JavaScript
framework for developing responsive, mobile-first web sites.
jQuery: jQuery is an open source JavaScript library that simplifies the interactions between
an HTML/CSS document, or more precisely the Document Object Model (DOM), and
JavaScript. Elaborating the terms, jQuery simplifies HTML document traversing and
manipulation, browser event handling, DOM animations, Ajax interactions, and cross-
browser JavaScript development.
SASS: It is the most reliable, mature and robust CSS extension language. It is used to extend
the functionality of an existing CSS of a site including everything from variables,
inheritance, and nesting with ease.
Some other libraries and frameworks are: Semantic-
UI, Foundation, Materialize, Backbone.js, Ember.js etc.
Other Important Points
Work with text editors to use shortcuts and its facilities i.e. Visual studio, Atom, Sublime etc.
Make UI responsible using grid system.
Git and git commands like init, add, commit etc for version control and to work with team.
Other tools like npm & yarn package managers, sass css pre-processor, browser DevTools
i.e. chrome devtools.
Understand using HTTP, JSON, GraphQL APIs to fetch data using axios or other tools.
It also requires some design skill to make layout and look better.
Back-end Technologies
It refers to the server-side development of web application or website with a primary focus on
how the website works. It is responsible for managing the database through queries and APIs by
client-side commands. This type of website mainly consists of three parts front end, back end,
and database. The back end portion is built by using some libraries, frameworks, and languages
which are discussed below:
PHP: PHP is a server-side scripting language designed specifically for web development.
Since, PHP code executed on server side so it is called server side scripting language.
C++ It is a general purpose programming language and widely used now a days for
competitive programming. It is also used as backend language.
Java: Java is one of the most popular and widely used programming language and platform.
It is highly scalable. Java components are easily available.
Python: Python is a programming language that lets you work quickly and integrate systems
more efficiently.
Node.js: Node.js is an open source and cross-platform runtime environment for executing
JavaScript code outside of a browser. You need to remember that NodeJS is not a framework
and it’s not a programming language. Most of the people are confused and understand it’s a
framework or a programming language. We often use Node.js for building back-end services
like APIs like Web App or Mobile App. It’s used in production by large companies such as
Paypal, Uber, Netflix, Walmart and so on.
Back End Frameworks: The list of back end frameworks are: Express, Django, Rails,
Laravel, Spring etc.
The other back end program/scripting languages are: C#, Ruby, REST, GO etc.
Other Important Points
Structuring the data in efficient way.
Handle request-response of APIs for storing and retrieve data.
Security of data is important.
Note: JavaScript is essential for all stacks as it is dominant technology on Web.
Database: Database is the collection of inter-related data which helps in efficient retrieval,
insertion and deletion of data from database and organizes the data in the form of tables, views,
schemas, reports etc.
Oracle: Oracle database is the collection of data which is treated as a unit. The purpose of
this database is to store and retrieve information related to the query. It is a database server
and used to manages information.
MongoDB: MongoDB, the most popular NoSQL database, is an open source document-
oriented database. The term ‘NoSQL’ means ‘non-relational’. It means that MongoDB isn’t
based on the table-like relational database structure but provides an altogether different
mechanism for storage and retrieval of data.
SQL: Structured Query Language is a standard Database language which is used to create,
maintain and retrieve the relational database.
GET: The GET request is typically used to retrieve data from the server, such as .html
files, images, or JSON data.
POST: POST requests are used when sending data to the server, such as adding an item
to a shopping cart or submitting a web form.
AJAX: Asynchronous JavaScript and XML (AJAX) is actually just a GET or POST
request that is done directly by JavaScript running in the browser. Despite the name, an
AJAX request can receive XML, JSON, or raw data in the response.
Rendering the Browser View
The screen that the user actually views and interacts with is often made up of several different
pieces of data retrieved from the webserver. The browser reads data from the initial URL and then
renders the HTML document to build a Document Object Model (DOM). The DOM is a tree
structure object with the HTML document as the root. The structure of the tree basically matches
the structure of the HTML document. For example, document will have html as a child,
and html will have head and body as children, and body may have div, p, or other elements as
children, like this:
document
+ html
+ head
+ body
+ div
+p
The browser interprets each DOM element and renders it to the user’s screen to build the webpage
view.
The browser often gets various types of data from multiple webserver requests to build a webpage.
The following are the most common types of data the browser uses to render the final user view as
well as define the webpage behavior:
JavaScript end-to-end: One of the biggest advantages of Node.js is that it allows you
to write both server- and client-side scripts in JavaScript. There have always been
difficulties in deciding whether to put logic in client-side scripts or server-side scripts.
With Node.js you can take JavaScript written on the client and easily adapt it for the
server and vice versa. An added plus is that client developers and server developers are
speaking the same language.
Event-driven scalability: Node.js applies a unique logic to handling web requests.
Rather than having multiple threads waiting to process web requests, with Node.js they
are processed on the same thread, using a basic event model. This allows Node.js
webservers to scale in ways that traditional webservers can’t.
Extensibility: Node.js has a great following and very active development community.
People are providing new modules to extend Node.js functionality all the time. Also, it
is very simple to install and include new modules in Node.js; you can extend a Node.js
project to include new functionality in minutes.
Fast implementation: Setting up Node.js and developing in it are super easy. In only a
few minutes you can install Node.js and have a working webserver.
MongoDB
MongoDB is an agile and very scalable NoSQL database. The name Mongo comes from the word
“humongous,” emphasizing the scalability and performance MongoDB provides. It is based on the
NoSQL document store model, which means data is stored in the database as basically JSON
objects rather than as the traditional columns and rows of a relational database.
MongoDB provides great website backend storage for high-traffic websites that need to store data
such as user comments, blogs, or other items because it is quickly scalable and easy to implement.
This book covers using the MongoDB driver library to access MongoDB from Node.js.
Node.js supports a variety of database access drivers, so the data store can easily be MySQL or
some other database. However, the following are some of the reasons that MongoDB really fits in
the Node.js stack well:
Document orientation: Because MongoDB is document oriented, data is stored in the
database in a format that is very close to what you deal with in both server-side and
client-side scripts. This eliminates the need to transfer data from rows to objects and
back.
High performance: MongoDB is one of the highest-performing databases available.
Especially today, with more and more people interacting with websites, it is important
to have a backend that can support heavy traffic.
High availability: MongoDB’s replication model makes it very easy to maintain
scalability while keeping high performance.
High scalability: MongoDB’s structure makes it easy to scale horizontally by sharding
the data across multiple servers.
Express
The Express module acts as the webserver in the Node.js-to-AngularJS stack. Because it runs in
Node.js, it is easy to configure, implement, and control. The Express module extends Node.js to
provide several key components for handling web requests. It allows you to implement a running
webserver in Node.js with only a few lines of code.
For example, the Express module provides the ability to easily set up destination routes (URLs) for
users to connect to. It also provides great functionality in terms of working with HTTP request and
response objects, including things like cookies and HTTP headers.
The following is a partial list of the valuable features of Express:
Route management: Express makes it easy to define routes (URL endpoints) that tie
directly to the Node.js script functionality on the server.
Error handling: Express provides built-in error handling for “document not found”
and other errors.
Easy integration: An Express server can easily be implemented behind an existing
reverse proxy system, such as Nginx or Varnish. This allows you to easily integrate it
into your existing secured system.
Cookies: Express provides easy cookie management.
Session and cache management: Express also enables session management and cache
management.
AngularJS
AngularJS is a client-side framework developed by Google. It provides all the functionality needed
to handle user input in the browser, manipulate data on the client side, and control how elements are
displayed in the browser view. It is written in JavaScript, with a reduced jQuery library. The theory
behind AngularJS is to provide a framework that makes it easy to implement web applications using
the MVC framework.
Other JavaScript frameworks could be used with the Node.js platform, such as Backbone, Ember,
and Meteor. However, AngularJS has the best design, feature set, and trajectory at this writing. Here
are some of the benefits AngularJS provides:
Data binding: AngularJS has a very clean method for binding data to HTML elements,
using its powerful scope mechanism.
Extensibility: The AngularJS architecture allows you to easily extend almost every
aspect of the language to provide your own custom implementations.
Clean: AngularJS forces you to write clean, logical code.
Reusable code: The combination of extensibility and clean code makes it very easy to
write reusable code in AngularJS. In fact, the language often forces you to do so when
creating custom services.
Support: Google is investing a lot into this project, which gives it an advantage over
similar initiatives that have failed.
Compatibility: AngularJS is based on JavaScript and has a close relationship with
jQuery. This makes it easier to begin integrating AngularJS into your environment and
reuse pieces of your existing code within the structure of the AngularJS framework.
JavaScript is a powerful language with a rich set of features that enable developers to create
dynamic and interactive web applications. Understanding its fundamentals is essential for anyone
looking to work in web development.
JavaScript programs can be inserted almost anywhere into an HTML document using
the <script> tag.
For instance:
<!DOCTYPE HTML>
<html>
<body>
<p>Before the script...</p>
<script>
alert( 'Hello, world!' );
</script>
<p>...After the script.</p>
</body>
</html>
javascript
Copy code
var name = "John";
let age = 30;
const isStudent = true;
Data Types: Common data types include strings, numbers, booleans, null, undefined,
objects, and arrays.
javascript
Copy code
let message = "Hello, World!"; // String
let count = 42; // Number
let isActive = true; // Boolean
let student = null; // Null
let course; // Undefined
2. Operators
Arithmetic Operators: +, -, *, /, %
javascript
Copy code
let sum = 10 + 5; // 15
let product = 10 * 5; // 50
Comparison Operators: ==, ===, !=, !==, <, >, <=, >=
javascript
Copy code
let isEqual = (5 == '5'); // true
let isStrictEqual = (5 === '5'); // false
javascript
Copy code
let result = (true && false); // false
let isNotTrue = !true; // false
3. Control Structures
javascript
Copy code
if (age > 18) {
console.log("Adult");
} else {
console.log("Minor");
}
javascript
Copy code
for (let i = 0; i < 5; i++) {
console.log(i);
}
4. Functions
Function Declaration
javascript
Copy code
function greet(name) {
return "Hello, " + name;
}
Function Expression
javascript
Copy code
const greet = function(name) {
return "Hello, " + name;
};
Arrow Functions
javascript
Copy code
const greet = (name) => "Hello, " + name;
javascript
Copy code
let person = {
firstName: "John",
lastName: "Doe",
age: 25
};
console.log(person.firstName); // John
javascript
Copy code
let numbers = [1, 2, 3, 4, 5];
console.log(numbers[0]); // 1
6. DOM Manipulation
JavaScript can interact with and manipulate the HTML DOM (Document Object Model).
javascript
Copy code
document.getElementById("myElement").innerHTML = "New Content";
7. Events
javascript
Copy code
document.getElementById("myButton").addEventListener("click", function() {
alert("Button clicked!");
});
8. Asynchronous JavaScript
Callbacks
javascript
Copy code
function fetchData(callback) {
setTimeout(() => {
callback("Data received");
}, 2000);
}
fetchData((data) => {
console.log(data);
});
Promises
javascript
Copy code
let promise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve("Promise resolved");
} else {
reject("Promise rejected");
}
});
promise.then((message) => {
console.log(message);
}).catch((message) => {
console.log(message);
});
Async/Await
javascript
Copy code
async function fetchData() {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
}
fetchData();
Understanding Node.js
Node.js is a runtime environment that allows you to run JavaScript code on the server side. It uses
the V8 JavaScript engine (the same one used by Google Chrome) to execute code, and it provides a
non-blocking, event-driven architecture for building scalable network applications.
Installing Node.js
1. Download Node.js:
o Visit the official Node.js website.
o Download the installer for your operating system (Windows, macOS, Linux).
2. Install Node.js:
o Run the installer and follow the instructions.
o Verify the installation by opening a terminal or command prompt and typing:
bash
Copy code
node -v
npm -v
This should display the installed versions of Node.js and npm (Node Package
Manager).
Node.js uses npm to manage packages (libraries and tools). With npm, you can install, update, and
remove packages easily.
1. Initialize a Project:
o Create a new directory for your project and navigate into it.
bash
Copy code
mkdir my-node-app
cd my-node-app
bash
Copy code
npm init -y
This creates a package.json file in your project directory, which keeps track of your
project's dependencies and configuration.
2. Installing Packages:
o Install a package (e.g., Express for web server functionality):
bash
Copy code
npm install express
javascript
Copy code
const express = require('express');
javascript
Copy code
const express = require('express');
const app = express();
2. Define Routes:
o Set up a simple route to handle requests:
javascript
Copy code
app.get('/', (req, res) => {
res.send('Hello, World!');
});
javascript
Copy code
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
bash
Copy code
node app.js
o Open a web browser and navigate to http://localhost:3000 to see the "Hello, World!"
message.
Node.js uses an event-driven model, where events trigger callback functions. This model is
implemented using an event loop, which continuously checks for new events and executes their
corresponding callbacks.
You can use functions like setTimeout, setInterval, and process.nextTick to add tasks to the event
queue.
setTimeout:
javascript
Copy code
setTimeout(() => {
console.log('This will run after 1 second');
}, 1000);
setInterval:
javascript
Copy code
setInterval(() => {
console.log('This will run every 2 seconds');
}, 2000);
process.nextTick:
javascript
Copy code
process.nextTick(() => {
console.log('This will run at the end of the current operation');
});
Implementing Callbacks
Callbacks are functions passed as arguments to other functions and are invoked after the completion
of certain tasks.
javascript
Copy code
function greet(name, callback) {
console.log(`Hello, ${name}!`);
callback();
}
function afterGreet() {
console.log('This function runs after the greet function');
}
greet('John', afterGreet);
javascript
Copy code
const fs = require('fs');
In this example, fs.readFile reads a file asynchronously, and the callback function is executed after
the file reading is complete.
UNIT-II
Node.js
Working with JSON, Using the Buffer Module to Buffer Data, Using the Stream Module
to Stream Data, Accessing the File System from Node.js- Opening, Closing, Writing,
Reading Files and other File System Tasks. Implementing HTTP Services in Node.js-
Processing URLs, Processing Query Strings and Form Parameters, Understanding
Request, Response, and Server Objects, Implementing HTTP Clients and Servers in
Node.js, Implementing HTTPS Servers and Clients. Using Additional Node.js Modules-
Using the OS Module, Using the Util Module, Using the DNS Module, Using the crypto
Module.
In Node.js, working with JSON (JavaScript Object Notation) is quite simple because JSON is
natively supported. Here are a few basic operations you can perform when working with JSON data
in Node.js:
You can use JSON.parse() to convert a JSON string into a JavaScript object.
Node.js provides a built-in module called fs (File System) to read from and write to files. You can
use this to read and write JSON files.
const fs = require('fs');
If you’re using Express.js, you can easily handle JSON data in request and response objects.
In this case, when you send a POST request with JSON data to /user, it will be parsed and logged.
This will catch and log the error if the JSON is malformed.
In Node.js, the Buffer module is used to handle raw binary data directly. Buffers are especially
useful when working with binary streams, files, or any other kind of raw data that doesn’t naturally
fit into JavaScript's typical string encoding.
1. Creating Buffers
You can create a buffer in a few ways, such as from a string, an array, or allocating a new buffer
with a specific size.
In this example, the string 'Hello, world!' is converted to a buffer using the UTF-8 encoding.
This creates a buffer from an array of numbers, where each number represents a byte in the buffer.
You can access the individual bytes of a buffer using its indices, just like an array.
Example:
const buffer = Buffer.from('Hello, world!');
console.log(buffer[0]); // 72 (ASCII code for 'H')
console.log(buffer[1]); // 101 (ASCII code for 'e')
3. Writing Data to a Buffer
You can modify data inside the buffer, as buffers are mutable.
4. Buffer Slicing
Buffers can be sliced into smaller buffers without copying the data.
Example:
5. Concatenating Buffers
You can concatenate multiple buffers into a single buffer using Buffer.concat().
Example:
6. Buffer Methods
Example of copy():
const buffer1 = Buffer.from('Hello, ');
const buffer2 = Buffer.from('world!');
buffer1.copy(buffer2, 0, 0, buffer1.length); // Copy "Hello, " into buffer2
Buffers are commonly used in scenarios involving file I/O, streams, or binary protocols. For
example, when reading files in binary mode, fs.readFile() returns a buffer.
const fs = require('fs');
The stream module in Node.js provides a powerful and flexible way to handle streaming data.
Streams allow you to process data piece-by-piece, which is particularly useful when working with
large amounts of data that may not fit into memory all at once, such as reading and writing files or
handling HTTP requests and responses.
1. Readable Streams: Streams that you can read from. Example: fs.createReadStream(), HTTP
requests.
2. Writable Streams: Streams that you can write to. Example: fs.createWriteStream(), HTTP
responses.
3. Duplex Streams: Streams that are both readable and writable. Example: a network socket.
4. Transform Streams: A special type of duplex stream that can modify the data as it is being
read or written. Example: zlib.createGzip() for compression.
Readable streams allow you to read data in chunks, which can be processed as the data is received
(avoiding the need to load the entire file into memory).
const fs = require('fs');
// Handle errors
readableStream.on('error', (err) => {
console.error('Error reading stream:', err);
});
Writable streams allow you to write data to a destination. Example: writing to a file, sending HTTP
responses.
const fs = require('fs');
// Create a writable stream
const writableStream = fs.createWriteStream('output.txt');
One of the most common use cases for streams is piping data from one stream to another. You can
use the .pipe() method to send data from a readable stream to a writable stream. This is particularly
useful for tasks like file copying, or reading from a network socket and sending the data to a file.
const fs = require('fs');
writableStream.on('finish', () => {
console.log('File has been copied!');
});
4. Transform Streams
A transform stream is a type of duplex stream where data is transformed as it is read and written.
For example, you could use it to compress data, convert it to a different format, or filter content.
const fs = require('fs');
const zlib = require('zlib');
writableStream.on('finish', () => {
console.log('File has been compressed!');
});
Streams are often used in web servers, especially when handling large HTTP requests and
responses.
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Streams in Node.js also support flow control, meaning you can control when data is read from a
stream. The default behavior is flowing mode, where data is read automatically as it becomes
available.
You can switch to paused mode if you want to control when data is read.
const fs = require('fs');
// Create a readable stream in paused mode
const readableStream = fs.createReadStream('example.txt', { highWaterMark: 16 });
7. Error Handling
Proper error handling is crucial when working with streams. You should listen for the 'error' event
on both readable and writable streams.
const fs = require('fs');
Streams are powerful for handling large or continuous data and are a fundamental part of Node.js
for I/O-bound tasks.
Node.js provides a built-in fs (file system) module that allows you to perform various tasks related
to files and directories, such as opening, closing, reading, writing, and manipulating files. The fs
module offers both synchronous and asynchronous methods to handle these tasks, which makes it
highly flexible for different use cases.
To interact with the file system, you first need to require the fs module:
const fs = require('fs');
2. Opening a File
The fs.open() method opens a file asynchronously, providing you with a file descriptor that you can
use for reading or writing.
Const fs=require(‘fs’);
fs.open('example.txt', 'r', (err, fd) => {
if (err) {
console.error('Error opening file:', err);
return;
}
console.log('File opened successfully with file descriptor:', fd);
});
If you prefer to use the synchronous version, you can use fs.openSync():
Const fs=require(‘fs’);
try {
const fd = fs.openSync('example.txt', 'r');
console.log('File opened successfully with file descriptor:', fd);
} catch (err) {
console.error('Error opening file:', err);
}
3. Closing a File
You can close an opened file using fs.close(), providing the file descriptor that you got from
fs.open().
Const fs=require(‘fs’);
fs.open('example.txt', 'r', (err, fd) => {
if (err) {
console.error('Error opening file:', err);
return;
}
Const fs=require(‘fs’);
try {
const fd = fs.openSync('example.txt', 'r');
fs.closeSync(fd);
console.log('File closed successfully');
} catch (err) {
console.error('Error closing file:', err);
}
4. Reading a File
The fs.read() method reads data from an opened file. You must first open the file using fs.open(),
and then you can read from it.
fs.open('example.txt', 'r', (err, fd) => {
if (err) {
console.error('Error opening file:', err);
return;
}
try {
const data = fs.readFileSync('example.txt', 'utf8');
console.log('File content:', data);
} catch (err) {
console.error('Error reading file:', err);
}
5. Writing to a File
The fs.write() method allows you to write data to a file. You must open the file first.
try {
fs.writeFileSync('example.txt', 'Hello, world!');
console.log('Data written to file');
} catch (err) {
console.error('Error writing to file:', err);
}
try {
fs.appendFileSync('example.txt', 'Appended data.\n');
console.log('Data appended successfully');
} catch (err) {
console.error('Error appending data to file:', err);
}
7. Renaming a File
8. Deleting a File
if (fs.existsSync('example.txt')) {
console.log('File exists');
} else {
console.log('File does not exist');
}
Summary
The fs module provides both asynchronous and synchronous methods for performing file system
operations. It is highly versatile, allowing you to:
For most I/O tasks, the asynchronous methods are preferred, as they avoid blocking the event loop,
making your application more efficient and responsive.
In Node.js, you can create HTTP services and handle requests using the built-in http module. The
http module allows you to process URLs, handle HTTP methods (GET, POST, PUT, DELETE,
etc.), and send responses to the client.
This basic server sends a "Hello, World!" message when you visit http://localhost:3000/ in your
browser.
When a client makes an HTTP request, it includes a URL that contains important information such
as the path, query parameters, and sometimes fragments. In Node.js, we can process these
components and use them to perform different actions.
To handle URLs and extract query parameters, we can use the url module, which provides utility
methods to parse and format URLs.
Example request:
Visit http://localhost:3000/products?category=electronics&price=1000
Path: /products
Query Parameters: { category: 'electronics', price: '1000' }
{
"message": "Request received",
"path": "/products",
"query": {
"category": "electronics",
"price": "1000"
}
}
The req (request) object contains the HTTP method (GET, POST, PUT, DELETE, etc.) that was
used in the request. We can check the HTTP method and route the request accordingly.
Example requests:
You can use dynamic route matching by processing parts of the URL path. You can extract variables
from the path using regular expressions or by splitting the URL path.
Example request:
Visit http://localhost:3000/user/12345
{
"message": "User details for user ID 12345",
"userId": "12345"
}
You can combine both dynamic path parameters and query parameters to create more sophisticated
URLs.
Example request:
Visit http://localhost:3000/products?category=electronics&price=1000
{
"message": "Displaying products in category electronics with price 1000",
"category": "electronics",
"price": "1000"
}
To handle requests for routes that are not defined, you can implement a default route that returns a
404 response.
Conclusion
In Node.js, handling HTTP requests and processing URLs is a core part of building HTTP services.
Using the built-in http and url modules, you can:
These techniques enable you to build flexible and efficient web services and APIs in Node.js.
In Node.js, processing query strings (from URLs) and form parameters (from POST requests) is a
common task, especially when building web applications or APIs. We can handle both of these types
of data with the help of built-in modules like url, querystring, and handling request bodies directly.
Let’s dive into how we can process query strings (GET requests) and form parameters (POST
requests) in Node.js.
Query strings are the part of the URL that comes after the ? character and are used to send data to
the server. They are typically used in GET requests.
Example URL:
http://localhost:3000/search?category=electronics&price=1000
category=electronics
price=1000
These are query parameters that we can extract from the request.
Node.js provides the url module to parse the request URL and extract query parameters.
Here’s how we can extract query parameters:
Example Request:
URL: http://localhost:3000/search?category=electronics&price=1000
Response:
{
"message": "Search results",
"category": "electronics",
"price": "1000"
}
In the example above, the code checks if the query parameters are provided. If they are missing, it
uses default values ('all' for category and 'any' for price).
Node.js does not parse the body of a POST request by default. To process form parameters, you
need to read the body and parse it.
You can use the querystring module (or URLSearchParams in newer Node.js versions) to parse form
data, but we’ll first need to collect the data from the request body.
URL: http://localhost:3000/submit
Form Data (submitted via a form):
o username=alice
o password=secret123
To simulate sending a POST request from a form, you can use curl or an HTML form.
Response:
{
"message": "Form submitted successfully",
"username": "alice",
"password": "secret123"
}
In modern web applications, it's common to send JSON data in POST requests, especially when
interacting with APIs. To handle JSON payloads, you need to parse the request body as JSON.
Response:
{
"message": "JSON data received",
"name": "John",
"age": 30
}
Sometimes, form data or query parameters can contain special characters that need to be encoded or
decoded properly. This can be done using encodeURIComponent and decodeURIComponent.
You can use these functions when constructing or processing URLs to handle special characters
properly.
Conclusion
In Node.js, you can process query strings (GET request parameters) and form parameters (POST
request body) using built-in modules like url, querystring, and http. Here are the main techniques we
covered:
Query Strings (GET Requests): Extracting data from the URL using url.parse().
Form Parameters (POST Requests): Parsing form data from the request body using
querystring.parse() for URL-encoded data.
JSON Data (POST Requests): Handling JSON payloads by parsing the body as JSON with
JSON.parse().
URL Encoding/Decoding: Using encodeURIComponent and decodeURIComponent to
handle special characters.
These are common tasks when building web services and APIs in Node.js, and these approaches can
be easily extended to handle more complex use cases.
In Node.js, the http module provides the core functionality to create HTTP servers and process
HTTP requests and responses. The http module's server is built around the request (req) and
response (res) objects, which play crucial roles in handling incoming requests and sending out
responses.
The request object represents the incoming HTTP request made by a client (e.g., a browser, mobile
app, or any HTTP client). It contains important information about the request such as headers, URL,
HTTP method (GET, POST, etc.), query parameters, request body, and more.
Key Properties of the req Object:
req.method: The HTTP method used for the request (e.g., 'GET', 'POST', 'PUT', 'DELETE').
req.url: The full URL of the request, including the path and query string (e.g., /home?
search=query).
req.headers: An object containing the request headers, such as User-Agent, Content-Type,
Authorization, etc.
req.body: This contains the body of the request, which is typically populated in POST and
PUT requests. It requires parsing (e.g., JSON or URL-encoded data).
req.query: Contains the query string parameters from the URL (e.g., ?name=John&age=30).
For parsing query strings, url.parse() can be used or express framework can parse it
automatically.
req.params: In routes with dynamic path parameters, the req.params object stores those
variables. For example, in a route like /user/:id, req.params.id will contain the value of id.
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Request details logged.');
});
server.listen(3000, () => {
console.log('Server is running at http://localhost:3000/');
});
The response object represents the HTTP response that the server sends back to the client. It
contains methods and properties for setting the status code, headers, and body of the response.
res.statusCode: Set the HTTP status code for the response (e.g., 200 for success, 404 for not
found).
res.setHeader(name, value): Set a specific HTTP header in the response. For example, you
can use res.setHeader('Content-Type', 'application/json') to set the response type to JSON.
res.end([data]): End the response and optionally send data (e.g., a string or a buffer). If no
data is provided, the response is ended with no body.
res.write(data): Used to send data in chunks (e.g., for streaming large files). You can call
res.write() multiple times, and finally call res.end() to finish the response.
res.json(obj) (in frameworks like Express): Sends a JSON response to the client. This is not
available in the core http module but can be implemented by calling
res.end(JSON.stringify(obj)).
server.listen(3000, () => {
console.log('Server is running at http://localhost:3000/');
});
The server object represents the HTTP server itself. It's an instance of the http.Server class, which is
created using http.createServer().
server.listen(port, hostname, callback): This method listens on the specified port (e.g.,
3000) and hostname (optional, usually 'localhost'). The callback function is executed once
the server starts.
server.close(): This method is used to stop the server from accepting new connections.
server.listen(3000, () => {
console.log('Server is running at http://localhost:3000/');
});
1. Server receives the request: The server created with http.createServer() listens for
incoming requests. When a request comes in, the callback function you provided is invoked,
and the req (request) and res (response) objects are passed to it.
2. Request processing: Inside the callback function, you inspect the req object to process the
request, including the HTTP method, headers, URL, and body. You can also access
parameters from the query string or URL path (e.g., req.query, req.params).
3. Response generation: After processing the request, you use the res object to build the
response. You can set status codes (e.g., res.statusCode = 200), set headers (e.g.,
res.setHeader('Content-Type', 'application/json')), and send the response body (e.g.,
res.end('Hello, World!')).
4. Server sends the response: Once the response is fully constructed, the res.end() method
sends the response back to the client.
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end(`Hello, ${name}!`); // Respond with a greeting message
} else {
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end('Not Found'); // Handle unknown routes
}
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
Example Request:
URL: http://localhost:3000/greet?name=John
Response:
Hello, John!
req (Request Object): Represents the incoming HTTP request. It contains details about the
request, such as the URL, HTTP method, headers, query parameters, and body data.
res (Response Object): Represents the outgoing HTTP response. You use it to set the status
code, headers, and body of the response.
server (Server Object): Represents the HTTP server that listens for incoming requests and
manages responses. It's created using http.createServer() and listens on a specified port.
Together, these objects form the core functionality for handling HTTP requests and responses in
Node.js.
In Node.js, you can implement both HTTP servers (to handle incoming requests) and HTTP
clients (to make requests to other servers). Node.js provides built-in modules such as http and https
to implement both.
An HTTP server listens for incoming HTTP requests from clients and sends responses. The http
module allows you to create a simple server by using the http.createServer() method.
Here is a basic example of creating an HTTP server that responds with "Hello, World!" for every
request.
Example: Creating an HTTP Server
Explanation:
An HTTP client in Node.js makes requests to other servers (e.g., sending a GET request to an API
or making a POST request). You can use the http module or the https module, depending on whether
you're connecting to a secure or non-secure server.
In this example, we will create an HTTP client that makes a GET request to a server.
Explanation:
http.request(options, callback): Makes an HTTP request to the server. The options object
specifies the hostname, path, and method (GET in this case).
res.on('data', callback): Listens for chunks of data that the server sends back in response.
res.on('end', callback): Fires when the entire response is received.
req.end(): Sends the request to the server.
You can also use the HTTP client to send data using the POST method.
Explanation:
method: 'POST': The HTTP method used to send data to the server.
headers: The Content-Type header tells the server that the body of the request contains
JSON data. The Content-Length header tells the server the length of the data being sent.
req.write(postData): Writes the data to be sent in the body of the request.
req.end(): Ends the request, sending the data.
When making requests with the HTTP client, it is important to handle errors. Errors can occur due
to network issues, timeouts, or server unavailability.
const options = {
hostname: 'jsonplaceholder.typicode.com',
path: '/nonexistent', // Invalid path to simulate an error
method: 'GET',
};
res.on('end', () => {
console.log('Response:', data);
});
});
req.end();
If you are making requests to a secure server (e.g., https:// URLs), you should use the https module
instead of the http module. The usage is the same, but it works for HTTPS connections.
res.on('end', () => {
console.log('Response:', data);
});
});
req.on('error', (err) => {
console.error('Error:', err.message);
});
req.end();
For more advanced HTTP client functionality (e.g., handling cookies, retries, redirects), you might
want to use external libraries like axios, node-fetch, or request (deprecated).
axios.get('https://jsonplaceholder.typicode.com/todos/1')
.then(response => {
console.log('Response:', response.data); // Log the response data
})
.catch(error => {
console.error('Error:', error.message);
});
Conclusion
In Node.js, you can build both HTTP clients and servers using the built-in http and https modules:
HTTP Server: Use http.createServer() to create a server that listens for incoming requests
and sends responses.
HTTP Client: Use http.request() or https.request() to send requests to other servers and
handle their responses.
POST Requests: Send data in the body of the request using req.write() for POST, PUT, or
PATCH methods.
For more advanced scenarios, you may want to explore external libraries like axios, which
simplifies making HTTP requests and handling responses.
In Node.js, you can implement both HTTPS servers (to handle secure incoming requests) and
HTTPS clients (to make secure requests to other servers). This is accomplished using the https
module, which provides the ability to create secure servers and clients that use SSL/TLS encryption.
To implement an HTTPS server in Node.js, you need an SSL/TLS certificate. These certificates are
used to encrypt the communication between the server and the client.
Prerequisites:
1. An SSL certificate (.crt) and a private key (.key). You can generate these using tools like
openssl, or use a service to obtain one.
2. These files will be used to configure the HTTPS server.
Explanation:
SSL/TLS Certificates: The key, cert, and optionally ca are used to configure the HTTPS
server. These files contain the server’s private key, certificate, and optionally the CA
certificate, respectively.
o key: The server's private key.
o cert: The server's public certificate.
o ca: The certificate authority's certificate (if needed).
https.createServer(options, callback): Creates an HTTPS server with the provided
SSL/TLS options.
Server listens on HTTPS port (3000): The server is configured to listen on port 3000 for
secure HTTPS connections.
An HTTPS client can be used to make secure requests to remote HTTPS servers. The https module
in Node.js is used to make these requests.
Example: Creating an HTTPS Client to Make a GET Request
Explanation:
In some cases, you might need to configure the HTTPS client to accept certain SSL/TLS certificates
(e.g., when dealing with self-signed certificates). You can pass SSL options in the https.request()
function.
Example: Using HTTPS Client with Custom SSL/TLS Certificates
// Define the options for the HTTPS request with custom SSL certificate
const options = {
hostname: 'example.com',
path: '/secure-endpoint',
method: 'GET',
cert: fs.readFileSync('path/to/certificate.crt'), // Client's SSL certificate
key: fs.readFileSync('path/to/private-key.key'), // Client's private key
ca: fs.readFileSync('path/to/ca-certificate.crt'), // Certificate authority's certificate
rejectUnauthorized: false, // Set to false if you want to allow self-signed certificates
};
res.on('end', () => {
console.log('Response:', data); // Log the response body
});
});
Explanation:
4. Self-Signed Certificates
If you are using self-signed certificates for local development or testing, you may need to add an
additional option to the client (rejectUnauthorized: false) to allow the connection, as self-signed
certificates are not trusted by default.
// Define the options for the HTTPS client with self-signed certificate
const options = {
hostname: 'localhost',
port: 3000,
path: '/',
method: 'GET',
ca: fs.readFileSync('path/to/self-signed-ca.crt'), // Path to self-signed CA certificate
rejectUnauthorized: false, // Allow self-signed certificates
};
res.on('end', () => {
console.log('Response:', data);
});
});
req.end();
If you want to test an HTTPS server locally with a self-signed certificate, you can generate one
using OpenSSL and then configure your HTTPS server accordingly.
To create a self-signed certificate for local testing, you can run the following OpenSSL command:
openssl req -x509 -newkey rsa:4096 -keyout private-key.key -out certificate.crt -days 365
Conclusion
HTTPS Server: Use the https module with an SSL/TLS certificate and private key to create
a secure server.
HTTPS Client: Use the https module to make secure requests to HTTPS servers, passing
SSL/TLS certificates if needed.
Self-Signed Certificates: If you're using self-signed certificates for local development,
configure both the client and server to allow them (e.g., rejectUnauthorized: false for the
client).
For more advanced use cases, you can also explore features like mutual TLS (client-side
authentication) and configure additional SSL options to enhance security.
The os module in Node.js provides a number of operating system-related utility methods that can be
helpful in retrieving information about the system, including CPU, memory, and network-related
data. It's a built-in module, so you don’t need to install anything extra to use it.
Here are some of the commonly used methods in the os module and how you can use them:
1.1. os.platform()
This method returns a string identifying the operating system platform. For example, it could return
'darwin' for macOS, 'linux' for Linux, or 'win32' for Windows.
const os = require('os');
console.log('Platform:', os.platform());
1.2. os.arch()
This method returns a string identifying the architecture of the operating system. It could return
'x64', 'arm', 'ia32', etc.
console.log('Architecture:', os.arch());
1.3. os.hostname()
console.log('Hostname:', os.hostname());
1.4. os.type()
This method returns a string identifying the operating system name (e.g., 'Linux', 'Darwin', or
'Windows_NT').
1.5. os.release()
1.6. os.uptime()
Returns the system uptime in seconds (how long the system has been running).
2.1. os.totalmem()
2.3. os.cpus()
Returns an array of objects containing information about each logical CPU core. Each object
contains details like model, speed, and times spent in user, system, and idle modes.
3.1. os.networkInterfaces()
Returns an object containing network interfaces that are available on the system. This is useful for
retrieving IP addresses and other network-related data.
{
"eth0": [
{
"address": "192.168.1.10",
"netmask": "255.255.255.0",
"family": "IPv4",
"mac": "00:1a:2b:3c:4d:5e",
"internal": false,
"cidr": "192.168.1.10/24"
}
],
"lo0": [
{
"address": "127.0.0.1",
"netmask": "255.0.0.0",
"family": "IPv4",
"mac": "00:00:00:00:00:00",
"internal": true,
"cidr": "127.0.0.1/8"
}
]
}
4.1. os.userInfo()
This method returns an object with the current user's information (e.g., username, home directory,
shell).
Example output:
{
"username": "your-username",
"uid": 501,
"gid": 20,
"shell": "/bin/bash",
"homedir": "/Users/your-username"
}
5.1. os.tmpdir()
6.1. os.endianness()
Returns the endianness of the system’s CPU. It can return 'BE' for big-endian or 'LE' for little-
endian.
console.log('Endianness:', os.endianness());
7.1. os.loadavg()
Returns an array with three load averages for the last 1, 5, and 15 minutes. This is usually a measure
of the system's load and how many processes are in the queue for CPU.
Example output:
8.1. os.constants
This provides system constants such as signals, file system flags, and error codes.
Example usage:
Here’s an example that combines some of the above methods to print a summary of system
information:
const os = require('os');
console.log('Platform:', os.platform());
console.log('Architecture:', os.arch());
console.log('Hostname:', os.hostname());
console.log('OS Type:', os.type());
console.log('OS Release:', os.release());
console.log('Uptime:', os.uptime(), 'seconds');
console.log('Total Memory:', os.totalmem(), 'bytes');
console.log('Free Memory:', os.freemem(), 'bytes');
console.log('CPUs:', os.cpus());
console.log('Network Interfaces:', os.networkInterfaces());
console.log('User Info:', os.userInfo());
console.log('Temporary Directory:', os.tmpdir());
console.log('Endianness:', os.endianness());
console.log('Load Average:', os.loadavg());
Conclusion
The os module is a valuable tool in Node.js for interacting with and retrieving system-related
information. It's commonly used when you need to gather data on the environment your application
is running on, such as CPU details, memory usage, and networking information.
The util module in Node.js provides a set of utility functions that help in working with objects,
functions, and other built-in JavaScript types. It can be quite useful for tasks such as inspecting
objects, formatting strings, and using inheritance, among other things.
1. util.format()
The util.format() function is similar to printf in other languages like C. It allows you to format
strings with placeholders, which are then replaced by the provided arguments.
Example:
const util = require('util');
You can use multiple placeholders, like %s for strings, %d for integers, %j for JSON, and more.
2. util.inspect()
Example:
const obj = {
name: 'John',
age: 25,
hobbies: ['reading', 'coding'],
};
3. util.promisify()
The util.promisify() function converts callback-based functions into ones that return a Promise. This
is especially helpful when you want to use async/await syntax with legacy callback-based APIs.
Example:
const fs = require('fs');
const util = require('util');
// Convert fs.readFile to return a promise
const readFilePromise = util.promisify(fs.readFile);
readFile();
This makes fs.readFile() return a promise instead of using a callback, allowing you to use
async/await with it.
4. util.callbackify()
util.callbackify() is the opposite of promisify(). It converts a function that returns a Promise into a
function that uses a callback. This can be useful when you're working with APIs that expect
callback-based functions.
Example:
The util.inherits() function is used for setting up inheritance in Node.js. It allows one constructor
function to inherit from another.
Example:
Animal.prototype.speak = function() {
console.log(`${this.name} makes a sound`);
};
// Set up inheritance
util.inherits(Dog, Animal);
Here, Dog inherits from Animal. The Dog class can now access methods from Animal.
6. util.deprecate()
The util.deprecate() function allows you to mark a function as deprecated, and it will show a
warning when the function is called.
Example:
// A deprecated function
function oldFunction() {
console.log('This function is deprecated');
}
This will print a warning when the function is called, alerting the developer that the function is
deprecated.
7. util.isArray()
This method checks if the given value is an array. It returns true if the value is an array, otherwise
false.
8. util.isError()
This method checks if the value is an instance of Error. It returns true if the value is an error,
otherwise false.
// Create an object
const obj = {
name: 'Alice',
age: 30,
greet: function() { return 'Hello, ' + this.name; },
};
// Deprecate a function
const deprecatedFunc = util.deprecate(function() {
console.log('This is deprecated');
}, 'This function is deprecated!');
Conclusion
The util module in Node.js offers a variety of utility functions that simplify working with
asynchronous code, object inspection, formatting, inheritance, and more. It’s a powerful tool for
developers working with Node.js, especially when dealing with legacy callback-based APIs,
debugging, or working with complex data structures.
The dns module in Node.js provides an API for performing DNS (Domain Name System) lookups
and resolving domain names. This module is essential when you need to interact with DNS records,
perform reverse lookups, or resolve hostnames to IP addresses.
Here’s an overview of how you can use the dns module in Node.js:
The dns module provides functions that allow you to resolve domain names into their respective IP
addresses. There are both callback-based and Promise-based versions of these methods.
2.1. dns.lookup()
Example:
Example Output:
Address: 172.217.6.36
Family: 4
2.2. dns.promises.lookup()
This is the Promise-based version of dns.lookup(). It returns a promise that resolves with the address
and family.
Example:
resolveHostname();
You can use the dns module to resolve various types of DNS records, such as A records, MX
records, and more.
3.1. dns.resolve()
The dns.resolve() method resolves a domain name into different types of records (like A, AAAA,
MX, etc.).
Example (A records):
const dns = require('dns');
Example Output:
3.2. dns.resolveMx()
The resolveMx() method retrieves the mail exchange (MX) records for a domain.
Example:
Example Output:
MX Records: [
{ exchange: 'alt1.gmail-smtp-in.l.google.com', priority: 5 },
{ exchange: 'alt2.gmail-smtp-in.l.google.com', priority: 5 },
{ exchange: 'gmail-smtp-in.l.google.com', priority: 10 },
{ exchange: 'alt3.gmail-smtp-in.l.google.com', priority: 5 },
{ exchange: 'alt4.gmail-smtp-in.l.google.com', priority: 5 }
]
3.3. dns.resolveTxt()
The resolveTxt() method retrieves the TXT records for a domain. TXT records are often used for
various domain-related configurations like SPF (Sender Policy Framework) records.
Example:
Example Output:
You can use the dns.reverse() method to get the hostnames for a given IP address. This is useful
when you want to perform a reverse DNS lookup to find out the domain associated with a given IP.
Example:
Example Output:
Hostnames: [ 'dns.google' ]
5. dns.resolveSrv()
This method resolves a domain name to its SRV (Service) records, which are used to define the
location of servers for specified services.
Example:
SRV Records: [
{ priority: 10, weight: 60, port: 5060, name: 'sipserver.google.com' }
]
6. dns.resolveNs()
The resolveNs() method retrieves the nameserver (NS) records for a domain.
Example:
Example Output:
7. dns.resolveCname()
The resolveCname() method resolves a CNAME (Canonical Name) record, which maps an alias
domain name to the canonical domain name.
Example:
Example Output:
8. dns.lookupService()
The dns.lookupService() method performs a reverse lookup to get the service for a specific IP
address and port.
Example:
Example Output:
Hostname: dns.google
Service: domain
Node.js DNS methods also support promise-based versions for cleaner asynchronous code using
async/await.
resolveMX();
Conclusion
The dns module in Node.js provides a rich set of methods to interact with DNS and perform domain
name resolution, reverse lookups, and retrieve various DNS record types. It supports both callback
and promise-based patterns, making it flexible for handling asynchronous operations.
This module is especially useful when building networked applications, setting up custom DNS
queries, or diagnosing DNS issues.
USING THE CRYPTO MODULE
The crypto module in Node.js provides a set of cryptographic functionalities that allow you to
perform tasks such as hashing, encryption, decryption, HMACs (Hash-based Message
Authentication Codes), and more. It's essential when building secure applications that need to
handle sensitive data.
To use the crypto module in Node.js, you can simply require it like this:
2. Creating Hashes
Hashing is the process of converting data into a fixed-length string, typically used for storing
passwords or verifying data integrity. The crypto module supports several hashing algorithms like
SHA-256, SHA-512, MD5, etc.
HMAC is used to verify both the data integrity and authenticity of a message. It uses a
cryptographic key along with a hash function.
The crypto module can be used to perform symmetric encryption (using the same key for both
encryption and decryption) and asymmetric encryption (using a pair of public and private keys).
AES (Advanced Encryption Standard) is a symmetric encryption algorithm. Both the encryption and
decryption use the same key.
RSA is a type of asymmetric encryption, where a public key is used for encryption, and a private
key is used for decryption.
The crypto module can be used to generate random data for various purposes like generating keys,
salts, or nonces.
You can also use the crypto.randomInt() method to generate a random integer.
PBKDF2 (Password-Based Key Derivation Function 2) is used to securely derive a key from a
password, making it more resistant to attacks like brute-forcing.
The crypto module allows you to sign data using a private key and verify it using a public key,
which is essential for ensuring data authenticity and integrity.
console.log('Signature:', signature);
8. Stream-Based Encryption
For larger data (such as encrypting/decrypting files), you can use streams to perform encryption in
chunks without loading the entire file into memory.
const fs = require('fs');
const crypto = require('crypto');
input.pipe(cipher).pipe(output);
const fs = require('fs');
const crypto = require('crypto');
input.pipe(decipher).pipe(output);
Conclusion
The crypto module in Node.js provides a wide range of cryptographic functions for hashing,
encryption, signing, key derivation, and more. It's essential for building secure applications,
handling sensitive data like passwords, and implementing encryption/decryption mechanisms.