Full Stack

Download as pdf or txt
Download as pdf or txt
You are on page 1of 35

UNIT V

REACT

MERN STACK – Basic React applications – React Components – React State – Express REST
APIs - Modularization and Webpack - Routing with React Router – Server-side rendering

I. MERN STACK:
The MERN stack is a popular full-stack development framework used to build modern web applications.
MERN is an acronym for MongoDB, Express.js, React, and Node.js, which together create a robust set of
tools for both front-end and back-end development:
1. MongoDB: A NoSQL database used for storing data in JSON-like, flexible documents. It is
designed for scalability and makes data management easier with dynamic schema.
2. Express.js: A lightweight and flexible web application framework for Node.js. It simplifies
the process of building web applications and APIs by providing essential tools for routing,
middleware, and server-side logic.
3. React: A powerful JavaScript library for building user interfaces, particularly single-page
applications (SPAs). It helps in creating reusable UI components and managing the view
layer of the application efficiently.
4. Node.js: A JavaScript runtime environment that allows developers to execute JavaScript
code outside a web browser. It enables server-side scripting, allowing the creation of scalable
and efficient back-end services.
1 React:
• React anchors the MERN stack.
• In some sense, it is defining component of MERN stack.
• Facebook maintains open-source JavaScript library React, which is useful for creating HTML views.
• Unlike AngularJS, React is not a framework.
It is a library.
Thus, it does not, by itself, dictate a framework pattern such as the MVC pattern.
• React is primarily used to handle the "View" part in the Model-View-Controller (MVC)
architecture, responsible for displaying the user interface. However, React doesn't enforce any
particular way to manage the rest of the application.
Facebook Invented React:
• React was originally developed by Facebook engineers for internal use to address specific
challenges in building user interfaces. After seeing its success, Facebook decided to make React
available to the public by open-sourcing it, allowing developers worldwide to use and contribute to
the library.
• Before React, Facebook used a standard client-side MVC (Model-View-Controller) architecture.
In this model, the View and Model were tightly coupled, enabling two-way data binding, meaning
changes in the user interface (View) could directly update the underlying data (Model) and vice
versa.
• This setup also involved templates, which are predefined structures or formats used to render the
user interface. Soon, this got pretty hairy as the application became more and more complex.
Declarative
• React's declarative nature means developers only describe how the UI should look, and React
handles the updates automatically. don’t need to manually manage changes to the DOM when
the view's state or data changes.
• A React component defines how the UI should appear based on the current data. Unlike jQuery,
where you manually update the DOM when data changes, React handles the updates
automatically.
• React automatically calculates the differences between the old and new views, applying only the
necessary updates. This approach ensures consistency, predictability, and makes the UI easier to
maintain and understand.
• In React, instead of refreshing the entire screen with every data change, the virtual DOM
efficiently updates only the parts that need changing. The UI is declared as a virtual
representation in memory, not directly as HTML or the actual DOM.
• React efficiently calculates the differences between the virtual DOM and the actual DOM,
applying only the necessary updates.
• This process introduces minimal overhead, as the algorithm for determining these differences is
highly optimized for performance.
Component-Based
Fundamental building block of React is a component, which maintains its own state and renders itself.
• In React, all do is build components.
• Then, put components together to make another component that depicts a complete view or page.
• A component in React encapsulates both its data state and how it renders that data, simplifying
application development by breaking it into manageable parts.
• Components communicate by passing read-only properties to child components and by sending
callbacks to parent components, allowing for organized data flow and interaction.
No Templates
• Many web frameworks use templates to simplify the creation of repetitive HTML elements,
requiring developers to learn a specific templating language.
• In contrast, React utilizes JavaScript itself to build repetitive or conditional DOM elements,
allowing developers to make use of their existing programming skills.
For example, when want to construct a table, write a for(...) loop in JavaScript or use the map()
function of an array.
There is an intermediate language to represent a virtual DOM, and that is JSX, which is very similar
to HTML.
It lets create nested DOM elements in a familiar language rather than hand- constructing them using
JavaScript functions.
• JSX is a markup syntax similar to HTML used in React, but it is not a programming language.
While it's commonly used for creating virtual DOM elements, developers can also choose to write
pure JavaScript if they prefer not to use JSX.
Isomorphic
• Isomorphic JavaScript allows the same code to run on both the server and the browser, enabling
Server-Side Rendering (SSR). This approach improves SEO by sending pre-rendered HTML to
the client, making it easier for search engines to index.
• It also allows developers to share components and logic, reducing code duplication. Overall, it
enhances performance and user experience by delivering faster content.
Node.js
• Node.js is a JavaScript runtime that allows JavaScript to run outside of a browser, similar to
how the Java Runtime Environment (JRE) runs Java programs.
• It uses Chrome's V8 engine to execute JavaScript code independently.
Node.js Modules
• In Node.js, multiple JavaScript files are managed without needing an HTML page.
• Each file can be treated as a module, we can split the code across these modules for better
organization.
• To use code from one module in another, simply load it with the require function. This makes
it easy to manage and reuse code across different files.
• Node.js comes with built-in core modules that are compiled into its binary.
• These modules provide essential features like accessing the file system, handling networking,
managing input/output operations, and interacting with the operating system directly.
Node.js and npm
• NPM is the default package manager for Node.js, used to install and manage third-party libraries
(packages) and their dependencies.
• The NPM Registry (www.npmjs.com) is a public repository where developers share their
modules.
• Originally focused on Node.js modules, NPM has expanded to manage packages for browser-
based JavaScript, such as jQuery and React. Although React can be included directly in HTML,
it's recommended to install it via NPM for better management.
• Tools like Browserify or Webpack are used to bundle modules, making them browser-ready.
NPM is now the largest and fastest-growing repository, surpassing other package managers like
Maven.
• It also has a unique conflict resolution technique that allows multiple conflicting versions of a
module to exist side-by-side to satisfy dependencies.
Node.js Is Event Driven
• Node.js uses an asynchronous, event-driven, non-blocking I/O model instead of relying on
threads like other languages for multitasking. While threads create the illusion of simultaneous
execution by switching tasks during blocked I/O operations (e.g., file reads), Node.js avoids
blocking entirely.
• Instead of waiting for tasks like file opening to complete, Node.js uses callbacks to handle the
results once the task finishes.
• This allows other code to run in the meantime, enhancing efficiency. It's similar to how
asynchronous Ajax calls work in web development.
• In Node.js, event-driven programming is a natural fit due to JavaScript features like closures.
Instead of relying on threads, Node.js handles multitasking using an event loop, which is a
queue of events and their associated callbacks.
• For example, when a file is ready to be read, it triggers the callback provided earlier. This event-
based approach makes Node.js applications fast and eliminates the need for complex thread
synchronization mechanisms like semaphores and locks.
• As a result, developers don't need to worry about managing concurrent tasks manually.
Express
• Node.js is a runtime that runs JavaScript, but writing a web server from scratch using it can be
challenging. That's where the Express framework comes in, making server development easier.
• Express allows you to define routes and handle HTTP requests using flexible patterns (like
regular expressions).
• It simplifies parsing request data (URL, headers, parameters) and managing responses (status
codes, cookies, headers).
• Additionally, Express supports middleware—custom code that can be inserted into the
request/response cycle for tasks like logging or authentication. This makes building full web
applications much more efficient.
MongoDB
MongoDB is the database used in the MERN stack .
It is a NoSql document-oriented database with a flexible schema and a JSON- based query language.
NoSQL – stands for non relational
• NoSQL databases are non-relational, meaning they don't rely on tables, columns, and strict
relationships like traditional databases do.
• They allow for horizontal scaling across multiple servers by compromising on strong consistency,
which only a few web-scale applications actually need.
• A major advantage of NoSQL is avoiding the impedance mismatch between object-oriented code
and relational tables, eliminating the need for ORM (Object Relational Mapping) layers.
• In databases like MongoDB, data is stored as objects or documents, making it easy to work with
data in a way that matches application memory.
Document-oriented:

• In MongoDB, a document-oriented database, data is stored as documents within collections,


unlike relational databases that use rows within tables.
• Each document has a unique identifier, automatically indexed for quick access. For example,
an invoice in MongoDB can be stored as a single document that includes customer details and
item lines, allowing for atomic operations on the entire invoice.
• This design enables deeply nested data structures, which can be directly indexed—something
relational databases struggle with.
• While MongoDB’s data is stored in a de-normalized form, leading to data duplication and
increased storage use, storage costs are low today, and updates to catalog entries are infrequent.
• This flexibility makes MongoDB well-suited for applications that need to handle complex,
nested data without the constraints of traditional relational models.
Schema-Less Structure

• No Fixed Schema Required: In MongoDB, objects can be stored without a pre-defined schema.
This allows flexibility, particularly useful in the initial stages of development, as developers don’t
need to define or modify columns in advance.
• Dynamic Document Structure: Documents within a single collection aren’t required to share the
same set of fields. This means fields can be added to documents as needed directly through the
application code, avoiding database migration scripts.
• Caveat on Data Consistency: Although this flexibility is advantageous in early development, it
shifts the responsibility for data consistency from the database to the application. For larger, more
stable applications, it’s often better to enforce some schema consistency to avoid data integrity
issues.

JavaScript-Based Query Language

• JSON-Based Queries: Unlike SQL for relational databases, MongoDB uses JSON-like syntax
for its query language, allowing for the creation, retrieval, updating, and deletion of documents
through JSON objects. This makes MongoDB’s queries easier to construct programmatically.
• Data Stored in BSON: MongoDB stores data in BSON (Binary JSON) format, which optimizes
space usage while keeping the data format close to JSON. When retrieving documents, they’re
returned as JSON objects, ready for immediate use in JavaScript applications.
• JavaScript Runtime Integration: MongoDB’s shell is built on a JavaScript runtime, similar to
Node.js, allowing developers to use JavaScript commands directly in the command line. Stored
procedures, equivalent to those in relational databases, can also be created using JavaScript
snippets that run on the server.

React-Router

• React-Router is a library for managing views in a React application. It enables smooth


transitions between different views while keeping the browser URL updated with the current
view state.
• Routing Functionality: Similar to server-side routing, React-Router allows developers to
associate URLs with specific code components.
• It handles the browser’s back button functionality, enabling users to navigate between views
without needing to reload the entire page.
• React-Router is simple to implement, offering essential routing features without additional
setup.

React-Bootstrap

• React-Bootstrap is a version of the popular CSS framework, Bootstrap, adapted for React
applications.
• It provides Bootstrap’s styling and functionality through React components, allowing developers
to build interfaces with pre-designed components.
• Besides React-Bootstrap, other UI libraries for React include Material-UI and Elemental UI,
which also offer individual components like date pickers and tree views.

Webpack

• Webpack is essential for bundling and modularizing client-side code in web development.
• Other tools like Bower and Browserify serve similar purposes, but Webpack is noted for its
ease of use and lack of need for additional tools (such as Gulp or Grunt) for managing builds.
• Webpack can bundle and “compile” code, transforming React’s JSX syntax into pure
JavaScript for compatibility with browsers. This compilation step ensures JSX code runs
smoothly in the final application.

Isomorphic

• Single-Page Applications (SPAs) traditionally struggled with SEO because search engines
couldn’t fetch data through AJAX or render JavaScript.
• Early solutions included tools like PhantomJS or Prerender.io to generate HTML pages for SEO
purposes.
• MERN Stack Solution: In the MERN stack (MongoDB, Express, React, Node.js), server-
rendering React pages is straightforward since JavaScript can run on both the client and server.
• When React runs on the browser, it fetches data and builds the page (DOM) on the client, typical
of SPA behavior.
• To make pages SEO-friendly, React can run on the server to fetch data and render HTML, which
is then sent to the client. This allows search engines to index the content more effectively.

II. BASIC REACT APPLICATIONS

Serverless -Hello World

Begin by creating a new HTML file, named index.html, using any text editor.

This file will serve as the container for the React app.

Basic HTML Structure:

• Use basic HTML tags, such as <html>, <head>, and <body>, to structure the file.
• The <head> section will contain the links to the required JavaScript libraries.

Including React Libraries:

• React is available as a JavaScript library that can be included directly in the HTML file using
the <script> tag.

The React library comes in two main parts:


React Core: Manages React components and their state.

ReactDOM: Converts React components to a format (DOM) that browsers can understand.

• Instead of installing React locally, you can use a Content Delivery Network (CDN) to access
the libraries online.

The URLs provided are:

React: https://unpkg.com/react@16/umd/react.development.js

ReactDOM: https://unpkg.com/react-dom@16/umd/react-dom.development.js

These links should be included within <script> tags in the <head> section of the HTML file.

Set Up a Container for React:

• Inside the <body>, add a <div> element with an id attribute (like id="content"). This <div>
will act as the container where the React elements will be rendered.

<div id=”content”><\div>

Using React.createElement():

• To create a React element, use the React.createElement() function, similar to


document.createElement() in regular JavaScript, but with more features.
• Prototype of React.createElement(): React.createElement(type, [props], [...children])

type: Specifies the type of element, like 'div', 'span', or a custom component.

props: An object containing HTML attributes (e.g., { title: "Hello" }).

children: Any nested elements or text content. Multiple children can be passed as additional
arguments or as an array.

Creating a Simple "Hello World" Element:

• The example suggests creating a <div> element with a title attribute that contains a <h1>
element with the text "Hello World!".
• This JavaScript code will go inside a <script> tag in the <body> section and will be used to
render the React element inside the container <div>.

• In React, a React element—created by calling React.createElement()—is a JavaScript object


that represents the UI to be displayed on the screen. This representation can include multiple, nested
elements that together form what is called the "virtual DOM."
• The virtual DOM differs from the real DOM (Document Object Model) in that it exists in the
browser’s JavaScript memory as an abstract, nested structure of React elements, rather than as actual
HTML elements.
• To render this virtual DOM on the screen, React elements must be converted to real DOM elements.
This is done by ReactDOM.render(), which translates each React element into corresponding
HTML elements through a series of document.createElement() calls.
• The ReactDOM.render() function requires two arguments: the React element to be rendered and
the target real DOM element where it should be placed, usually a <div> with a specific ID.

To test this file, follow these steps:

1. Open the file in a web browser: This will load the HTML and React code.
2. Wait for React to load: It might take a few seconds for the React libraries to load fully,
especially if they are imported from a remote source.
3. Check the screen: Once loaded, you should see a caption displayed on the browser screen,
as shown in Figure 5.2 (a reference image from your document).
4. Hover over the area: Move your mouse over the text or anywhere to its right side, within
the boundaries of an outer <div> element. When you do this, a tooltip (a small text box) with
the message "Outer div" should pop up, indicating the boundaries of that outer <div>.

JSX:

• JSX (JavaScript XML) is a syntax extension for JavaScript that looks similar to HTML. It is used
in React to define the structure of UI components in a way that’s more readable and similar to
traditional HTML.
• While it resembles HTML, JSX is not exactly the same—there are some differences in syntax.
Instead of writing complex React.createElement() calls to create an element or a hierarchy of
elements, JSX allows us to write HTML-like code that is easier to understand and manage.
• For simple elements, like a "Hello World" message, JSX looks almost identical to HTML. You
can write the element directly as you would in HTML, and assign it to a variable, effectively
replacing the need for React.createElement() calls.

• In JSX, markup isn’t enclosed within quotes, so it’s not treated as a string, and it can't be directly
used as inner HTML.
• Instead, JSX is a syntax that combines HTML-like elements with JavaScript, and this markup is
directly compiled into React.createElement() calls by React's compiler
• JSX is easy to read and understand because it resembles HTML, but browsers don’t natively
understand it.
• Therefore, JSX needs to be converted into regular JavaScript with React.createElement() calls,
which requires a compiler. Babel is the tool commonly used for this transformation.
• For production, it’s best to pre-compile JSX before sending it to the browser. However, for quick
testing or prototyping, Babel provides a standalone compiler that runs directly in the browser,
available as a JavaScript file on unpkg.

• To let Babel know which scripts to transform, you need to add the attribute type="text/babel" to your
script tags. Babel will look for this attribute and then transform and execute any script marked with
it.
Project Setup

• server-less setup for React allows you to quickly start developing without installations or
running a server. You can include React and related libraries via Content Delivery Network
(CDN) links in your HTML file.
• Using a server instead of a server-less setup improves project organization and performance,
especially for larger applications.
• In production environments, runtime compilation of JSX can slow down page loading and
negatively impact user experience.
• To address this, it's recommended to serve all files from an HTTP server and organize your
project and folder structure accordingly.
• Instructions for commands you will use in the terminal are available in a file called
commands.md located in the root of your GitHub repository.
Setting Up Node.js with nvm

• nvm (Node Version Manager): This tool simplifies the installation and management of
multiple Node.js versions. You can install Node.js directly, but using nvm is more flexible.
• Installation Instructions:
o For Mac OS or Linux, follow the instructions on nvm's GitHub page.
o Windows users can search for "nvm for Windows" or install Node.js directly.
• PATH Initialization: nvm modifies your shell's initialization scripts to set up the PATH
variable. This allows nvm to recognize the different installed versions of Node.js the next
time you open a terminal.

Installing Node.js

• Once nvm is installed, you can use it to install Node.js.


• It's recommended to install the latest Long-Term Support (LTS) version, which is typically a
stable version that receives updates for an extended period (for example, Node.js version 10).

$ nvm install 10

→ installed Node.js, let's make that version the default for future

$ nvm alias default 10

This command ensures that version 10 will be used by default whenever you open a new terminal
session.

You can confirm the version of node that's been installed as your default by typing following in a new
shell or terminal:

$ node-version

Installing Node.js through nvm includes npm, so you don't need to install npm separately.

Direct Installation: If you choose to install Node.js directly (without nvm), make sure to also install a
compatible version of npm to manage your packages effectively.

You can confirm this by noting down the version of npm that was installed along with Node.js:

$ npm-version

Use npm -version to check the current npm version.

Verify the installation with npm -v to confirm the version update.

$ npm install-g npm@6

Install a specific version with npm install -g npm@6, ensuring you include the -g flag for global
installation.

Project

✓ Before we install any third-party packages with npm, it's a good idea to initialize the project.
With npm, even an application is considered a package.

Package Definition and Dependencies

• A package contains various attributes of your application, including a list of other packages
(dependencies) that your application relies on.
• These dependencies may change over time as you add new libraries and features to your
application.

Setting Up the Project Directory

1. Create a Project Directory:


o Create a directory to host your application, for example, pro-mern-stack-2.
2. Initialize the Project:
o Navigate into your project directory and run:

npm init

o This command initializes a new Node.js project and creates a package.json file,
which will store the project’s metadata and dependencies.
3. Project Directory Best Practices:
o Ensure you remain in the project directory for all shell commands, especially
for npm commands. This will localize all changes and installations to that
directory.

Installing and Managing Packages

• To install a package using npm, use the command:

npm install <package>

• Example: To install Express, simply run:

npm install express

• Uninstalling and Installing a Specific Version:


o You can uninstall a package and then install a specific version like this:

npm uninstall express


npm install express@4

Benefits of Local Installations

• All installations are local to the project directory, which allows different projects to use
different versions of the same package.
• This feature is beneficial when working on multiple Node.js projects, as it prevents unwanted
upgrades or changes to package versions that might affect your project.
III.REACT COMPONENTS

Components are independent and reusable bits of code. They serve the same purpose as JavaScript
functions, but work in isolation and return HTML.

Components come in two types, Class components and Function components

React Class Component

A class component must include the extends React.Component statement. This statement
creates an inheritance to React.Component, and gives your component access to
React.Component's functions.

The component also requires a render() method, this method returns HTML.

Example:
…………………..
class Car extends React.Component {
……………
}
……
With in the class a render() method is used, which should return aa element.
Can use the sane JSX <div> with the message as the returned element.

render(){
return(
<div title=”example”>
<h1>{message}</h1>
</div>
);
…..

Code for message construction within the render() function


A simple React class and instance

class HelloWorld extends React.Component {

render() {

const continents = ['Africa', 'America', 'Asia', 'Australia', 'Europe'];

const helloContinents = Array.from(continents, c => `Hello ${c}!`);

const message = helloContinents.join(' ');

return (

<div title="Outer div">

<h1>{message}</h1>

</div>

);

Composing Components:

It is possible to build a component that uses other user defined components as well is called
component composition, and it is one of the most powerful features of react.

Example:

Design main page of application as three parts:

1. A filter to select which issues to display


2. List of issues
3. An entry form for adding an issue

class IssueFilter extends React.Component {


render() {
return (
<div>This is a placeholder for the issue filter.</div>
);
}
}

class IssueTable extends React.Component {


render() {
return (
<div>This is a placeholder for a table of issues.</div>
);
}
}

class IssueAdd extends React.Component {


render() {
return (
<div>This is a placeholder for a form to add an issue.</div>
);
}
}

class IssueList extends React.Component {


render() {
return (
<React.Fragment>
<h1>Issue Tracker</h1>
<IssueFilter />
<hr />
<IssueTable />
<hr />
<IssueAdd />
</React.Fragment>
);
}
}
const element = <IssueList />;
ReactDOM.render(element, document.getElementById('contents'));

IV. REACT STATE

In React, state refers to the data that represents the current condition or values of a component.
The state allows React components to keep track of and manage dynamic information, such as
user input, API responses, or changes in the component's internal state.

Here are key points about the state of React:


1. Dynamic Data: State is used to manage data that can change over time during
the lifecycle of a React component. It allows components to be dynamic and responsive
to user interactions.
2. Local to Component: Each component in React can have its state, which is independent
of the state of other components. This encapsulation of state helps in building modular
and reusable components.
3. Initialization: State is typically initialized in the component's constructor in class
components or using the useState hook in functional components.

Initial State in React

State in a Component:

• A component’s state is stored in an object called this.state, containing key-value pairs.


• Each key represents a state variable, and each value is the current value of that variable.
• State is useful for storing data that impacts the rendered view and can change due to
events (e.g., user interaction).
• For the IssueTable component, the list of issues being displayed should be stored in state.
• This allows the list to update automatically when an issue is added, edited, or deleted,
impacting the component's view.
• Even if the display (e.g., line wraps due to a narrower window) changes, the browser
handles it directly without modifying the DOM, as the underlying data remains the same.
• Initially, an array of issues is stored as a component state, which is used to generate the
list of issues in the table.
• In the render method, IssueTable should use the issues array from this.state to
dynamically generate a list of IssueRow components:

const issueRows = this.state.issues.map(issue =>

<IssueRow key={issue.id} issue={issue} />

);

Setting Initial State:

• To start, a hard-coded list of issues can be set as the initial state.


• An example array initialIssues can be defined outside the component, and then this array
is set as the initial state to make it clear it’s only for initialization:

const initialIssues = [

// Define some initial issues here

];

For example, if you have an array initialIssues with initial data, you can set it as the initial value
for the state variable issues like this:

this.state = {

issues: initialIssues

};

If you need additional state variables, like a page number for pagination, you can add more
keys to this.state, such as:

this.state = {

issues: initialIssues,

page: 0

};
Async State Initialization

In React, while we initialize state in the constructor, real-world applications often fetch
initial data asynchronously, like from an API. In the case of an Issue Tracker, we would fetch
the list of issues from a server. Since the constructor only allows synchronous state
initialization, we start with an empty array and then update it after the data is fetched.

Initial State in Constructor:

• Set issues to an empty array initially in the constructor:

constructor() {

super();

this.state = { issues: [] };

Asynchronous Data Fetching:

• After the component mounts, fetch data from the server and update the state with the
fetched data using this.setState().
• this.setState() merges new data with existing state values without overwriting other state
variables (e.g., page).

Example of Async Fetch:

• Use componentDidMount() to fetch data after the component has loaded:

async componentDidMount() {
const newIssues = await fetchIssuesFromServer(); // Assume this fetches the issues

this.setState({ issues: newIssues });

State Update :

If there are additional state variables (e.g., page), this.setState({ issues: newIssues })
only updates issues without affecting other state values.

To update part of the state in React, you can modify only a specific portion, rather than
replacing the entire state.

1. Adding a New Issue: Define a method in IssueTable to add a new issue.


2. Generate ID and Creation Date: Use the current length of the issues array for the new
ID, and set the creation date to the current date.

Example:

createIssue(issue) {

issue.id = this.state.issues.length + 1;

issue.created = new Date();

V.EXPRESS REST APIS

REST (Representational State Transfer) is an architectural style used for building web services.
It defines a set of guidelines that allow a client and a server to communicate over HTTP. In a
RESTful architecture:

• A client sends requests to a server to interact with resources (data or functionality), and
the server responds with the requested data or an acknowledgment of an action
performed.
• Resources are any pieces of data or services that the server can provide, such as user
profiles, images, or search results.
• REST APIs use standard HTTP methods (GET, POST, PUT, DELETE, etc.) to access
or modify resources on the server.

API Client: An API client is the component that initiates requests to the REST API. There are
two main types of API clients:

1. Development Tool: This is a tool (like Postman or Insomnia) that simplifies sending
API requests. It allows developers to test, debug, and explore APIs without needing to
write code.
2. Application Service: In a software application, an API client refers to the code that
makes requests to an API server. It uses language-specific libraries or SDKs to send
requests and handle responses. This type of client might also process the returned data
and use it in the application’s logic, such as displaying information to users or
performing further operations.

API Request

An API request is a message sent by the client to the server, asking the server to perform a
specific action or provide certain data. The structure of an API request can vary depending on
the type of API, but for REST APIs, it generally includes the following components:

1. Endpoint:
o This is the URL that specifies the resource the client wants to interact with. The
endpoint directs the request to the correct location on the server. For example,
in an e-commerce app, a "products" endpoint would handle requests related to
product data (e.g., retrieving a list of products).
2. Method:
o The method determines the type of operation the client wants to perform on the
resource. In REST APIs, standard HTTP methods are used:
▪ GET: Retrieve data from the server.
▪ POST: Create new data on the server.
▪ PUT: Update existing data.
▪ PATCH: Partially update existing data.
▪ DELETE: Remove data.
o For example, a GET request to the "products" endpoint would ask the server to
return all the products in the database.
3. Parameters:
o These are values sent with the request to provide specific instructions or filter
the data. Parameters can be included in the URL, query string, or request body.
o For example, a parameter like "color" might be used in the "products" endpoint
to return only products of a specific color (e.g., products?color=red).

Request Headers

API request headers are key-value pairs included in the request to provide additional context
or instructions for the server about the request. Some common headers include:

• Content-Type: Specifies the format of the data in the request body (e.g.,
application/json or application/xml).
• Authorization: Provides authentication credentials to validate the requester, such as an
API key or OAuth token.

These headers are essential for the server to understand the request and ensure proper handling
(e.g., correct data format or proper user access).

Request Body

The request body contains the actual data that is needed to create, update, or delete a resource.
For example:

• If an admin wants to create a new product on an e-commerce site, the request body
might include the product’s name, brand, and price.
• The API specification will define the required data format for the request (commonly
JSON or XML).
API Server

The API server is the component that processes incoming requests from clients. Its
responsibilities include:

• Authentication: Verifying the client's identity using credentials like API keys or
tokens.
• Input Validation: Ensuring the request data is correct and adheres to expected formats.
• Database Interaction: The API server retrieves, manipulates, or updates data stored in
the database based on the client’s request.
• Response Generation: After processing the request, the server generates and sends a
response back to the client.

Although the database itself is not directly part of the API, it stores and organizes the data that
the API server uses. The API server serves as an intermediary, facilitating communication
between the client and the database to process and respond to requests efficiently.

API Response

Once the API server processes a request, it sends an API response to the client. This response
typically includes:

• Status code: Indicating the success or failure of the request (e.g., 200 OK for success,
404 Not Found for an error).
• Response body: The actual data or result of the operation (e.g., the list of products, a
confirmation message).

Components of an API response:

1. Status Code

The status code is an HTTP code returned by the server to indicate the outcome of the client’s
request. It helps the client understand whether the request was successful or if there was an
issue. Some common status codes include:

• 200 OK: The request was successful, and the server returned the requested data.
• 201 Created: The request was successful, and a new resource has been created (e.g., a
new product added to a database).
• 404 Not Found: The server could not find the requested resource (e.g., the product does
not exist).

Status codes are essential for the client to understand how to handle the response, such as
whether to display the requested data or show an error message.

2. Response Headers

Response headers provide additional information about the server's response. They are similar
to request headers but are used to give context about the response. Some common response
headers include:

• Cache-Control: Specifies how long the response data can be cached by the client or
intermediate caches (e.g., browsers or CDNs).
• Set-Cookie: Sets cookies in the client’s browser, often used for session management or
authentication purposes (e.g., saving a user’s login session).

These headers guide the client in processing or storing the response.

3. Response Body

The response body contains the actual data or content returned by the server in response to the
API request. It can vary depending on the type of request and the data being returned. Typically,
the body includes:

• Structured data objects that represent the requested resources, such as a product's
name, price, and description in a JSON or XML format.
• Metadata, such as the timestamp or source of the data.
• Error messages or details if the request failed, explaining what went wrong (e.g., if the
requested product was not found).

For example, a GET request for a product might return a response body containing a JSON
object with the product’s details (e.g., name, price, description), a timestamp of when the data
was retrieved, and information about the data source.

Example:

const express = require('express');


const app = express();
const port = 3000;

// Sample in-memory movie data (usually, this would come from a database)
let movies = [
{ id: 1, title: "Inception", director: "Christopher Nolan", year: 2010 },
{ id: 2, title: "The Matrix", director: "The Wachowskis", year: 1999 }
];

// Middleware to parse JSON request bodies


app.use(express.json());

// 1. Get all movies


app.get('/movies', (req, res) => {
res.status(200).json(movies);
});
// 2. Get a movie by ID
app.get('/movies/:id', (req, res) => {
const movie = movies.find(m => m.id === parseInt(req.params.id));
if (!movie) return res.status(404).json({ message: "Movie not found" });
res.status(200).json(movie);
});

// 3. Add a new movie


app.post('/movies', (req, res) => {
const { title, director, year } = req.body;
const newMovie = {
id: movies.length + 1,
title,
director,
year
};
movies.push(newMovie);
res.status(201).json(newMovie);
});

// 4. Update a movie
app.put('/movies/:id', (req, res) => {
const movie = movies.find(m => m.id === parseInt(req.params.id));
if (!movie) return res.status(404).json({ message: "Movie not found" });

const { title, director, year } = req.body;


movie.title = title || movie.title;
movie.director = director || movie.director;
movie.year = year || movie.year;

res.status(200).json(movie);
});
// 5. Delete a movie
app.delete('/movies/:id', (req, res) => {
const movieIndex = movies.findIndex(m => m.id === parseInt(req.params.id));
if (movieIndex === -1) return res.status(404).json({ message: "Movie not found" });
const deletedMovie = movies.splice(movieIndex, 1);
res.status(204).send();
});

// Start the server


app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Sample REST ful API-http methods
VI. MODULARIZATION AND WEBPACK
In modularization and Webpack for front-end development, we are breaking down large codebases
into smaller, more manageable components. Let’s go through the key concepts mentioned:
Webpack for Modularization
Webpack is a powerful tool for bundling and optimizing front-end code. It helps split the code into
smaller modules (such as components) and only loads them as needed. This improves performance by
loading parts of the application incrementally rather than all at once.
• Code Splitting: Webpack can break down the code into smaller chunks and load only what’s
necessary for the current page or feature, improving load times.
• Live Reloading: With the help of tools like webpack-dev-server, Webpack can refresh the
browser automatically every time you make changes to your code, making the development
process faster and more efficient.
• Component-based Development: In frameworks like React, modularization allows you to
build your application using smaller, reusable components.
For a React app, create-react-app can serve as a boilerplate, offering a pre-configured Webpack setup
to get started quickly. However, this only handles the front-end (React part) of your application.
MERN Stack with Webpack
• MERN stands for MongoDB, Express, React, Node.js — a full-stack JavaScript
framework. Using mern.io can help you generate the entire directory structure for a MERN-
based application, including back-end and front-end files, and integrate Webpack for module
bundling.
Back-End Modules in Node.js
When you work with Node.js, you need to modularize the code to make it more organized and
maintainable. This is done by splitting the code into separate modules (e.g., one module for database
handling, another for authentication, etc.).
Node.js uses the CommonJS module system, where:
• require() is used to import external modules or other files.
• module.exports is used to export functions, objects, or variables from a file so they can be
used elsewhere.
In Node.js, modules are identified by either the package name (for npm packages) or the file path (for
local modules). When using require():
• For npm packages, the ID is the name of the package (which corresponds to a folder inside
node_modules).
• For local modules within the same application, the ID is the path to the file, such as ./other.js.
To use a module in another file:
1. Exporting: A module's content (function, variable, etc.) is exported using module.exports in
the module file (e.g., other.js).
2. Importing: The require() function is used to import the module, and whatever is exported is
assigned to a variable.
For example, in other.js:
module.exports = function() {
console.log("Hello from other.js");
};
And in server.js:
// server.js
const other = require('./other.js');
other(); // Outputs: Hello from other.js

Front end Modules and Webpack


In front-end development, when your JavaScript code grows, managing multiple files
becomes cumbersome. Traditionally, you would include all JavaScript files in your HTML using
<script> tags, but this becomes unmanageable as the project grows.
Webpack and Browserify are tools that help manage this by bundling your application code
and its dependencies into one or a few optimized JavaScript files. These tools use require() statements
(similar to Node.js) to track both your application's and third-party dependencies.
The downside is that this process requires a build step. However, Webpack and Browserify
integrate with Babel to automatically transform modern JavaScript (like JSX and ES6) into browser-
compatible code.
To streamline the process, Gulp can be used as a task runner to automate bundling,
transformation (with Babel), and file-watching. This creates a smooth workflow for building and
developing front-end applications efficiently.
VII.ROUTING WITH REACT ROUTER
In a single-page application (SPA), multiple views or logical pages exist, but only the initial page is
loaded from the server. Subsequent views are displayed by manipulating the DOM without fetching the
entire page again.
Routing in SPAs connects the state of the page to the URL in the browser. It makes it easier to manage
and understand what is displayed based on the URL, providing the following benefits:
1. Better Navigation: Users can navigate between views without reloading the entire page.
2. Bookmarkable URLs: Each view has its own URL, which can be bookmarked or shared.
3. State Preservation: The URL reflects the current state of the application, making it easier to
track and manage.
In Single-Page Applications (SPAs), users can navigate between views using the browser's
forward/back buttons, and individual views can be bookmarked and shared via unique URLs. For
example, if someone encounters an issue on a specific view, they can share the URL directly, making
it easier for others to access the same state of the app.
Historically, SPAs only had a single URL, and all navigation was interactive. Users had to manually
follow a sequence of steps to reach a specific view. However, routing allows the page's state to be
reflected in the URL, making it easier to navigate and share specific views.
Hash-based Routing:
One common method for routing in SPAs is hash-based routing, which uses the URL's anchor portion
(everything after the # symbol). Here’s how it works:
• The part of the URL before the # remains constant (e.g., index.html), representing the single
page of the SPA.
• The hash part (#something) determines which section of the page is displayed, reflecting
different views within the application.
• This method is simple, doesn’t require complex server-side configurations, and can be
implemented easily without a routing library.

Browser History & HTML5 API:

• In modern SPAs, HTML5's browser history API allows JavaScript to handle URL
changes without reloading the page. This enables navigation between different views
within the application while maintaining the same page load.
• This method is more complex than hash-based routing, as it requires handling
different URL requests from the server. However, it's especially useful when we want
to fully render a page from the server and ensure that search engines can crawl and
index the content correctly.

Simple Routing Example:


In this section, you are setting up basic routing in a React application using React Router:
1. Two Views:
o Issue List View: This will display the list of issues you’ve been working on.
o Report View: A placeholder component will be created to represent the report
section.
2. Home Page Redirection: The homepage will automatically redirect to the issue list.
3. React Router Setup: To handle the routing, you’ll install the React Router package using
npm:
npm install react-router-dom
4. Creating a Report Component:
o You will create a new file called issueReport.jsx in the src/ui directory.
o This component will serve as a placeholder for the report section, displaying a simple
message:
import React from 'react';
export default function IssueReport() {
return <div><h2>This is a placeholder for the Issue Report</h2></div>;
}
splitting the main page of the application into two sections:
1. Header Section: This will contain a navigation bar with hyperlinks to different views
(pages) of the application. The navigation bar will remain visible, no matter which view is
displayed.
2. Content Section: This section will switch between views based on the hyperlink selected in
the navigation bar.
Steps:
1. Create a Content Component:
o This component will handle view switching based on the route selected from the
navigation bar.
o Save it as Contents.jsx under the src/ui directory.
2. Routing:
o Use React Router to handle routing between the views.
o The Route component from React Router is used to map a URL path to a specific
component.
o In this case, when the URL path is /issues, the Issue List view will be shown, and
when the URL is /report, the Issue Report view will be shown.
Example:
<Route path="/issues" component={IssueList} />
<Route path="/report" component={IssueReport} />
3. Redirection:
o To redirect the home page (i.e., /) to /issues, you use the Redirect component.
o This will automatically navigate the user to the issues page when they visit the home
page.
<Redirect from="/" to="/issues" />
4. Handle No Matching Routes:
o If no route matches the current URL, show a fallback message. This can be done
using a default Route with no path specified or by adding a "catch-all" route.
In React Router, the order and configuration of routes are very important.
Match Any Path:
o In React Router, you can use a route that matches any path using a catch-all route.
This is helpful when you want to display a "Page Not Found" message if none of the
other routes match.
o You can achieve this by defining a route without a path attribute, like this:
const NotFound = () => <h1>Page Not Found</h1>;
<Route component={NotFound} />
2. Using <Switch>:
o The <Switch> component ensures that only the first matching route is rendered,
which is crucial when you have multiple routes with similar or overlapping paths.
Without <Switch>, React Router would render all routes that match the URL, not
just the first one.
Example:
<Switch>
<Route path="/issues" component={IssueList} />
<Route path="/report" component={IssueReport} />
<Route component={NotFound} /> {/* Catch-all route */}
</Switch>
3. Exact Matching:
o By default, React Router uses prefix matching. This means that a route like /issues
will match both /issues and /report because / is a prefix to both.
o To avoid this and ensure that the route only matches the exact path, use the exact
property on the route. For example:
<Route exact path="/issues" component={IssueList} />
4. Route Order:
o The order of routes matters because React Router will match the first path that fits.
For example, if you have both a /issues route and a general catch-all route like /, the
general route might be matched first.
o Therefore, it's important to place more specific routes (like /issues or /report) before
the general catch-all route (like * or /).
<Switch>
<Route exact path="/issues" component={IssueList} />
<Route exact path="/report" component={IssueReport} />
<Route component={NotFound} /> {/* Catch-all route */}
</Switch>
VII.SERVER-SIDE RENDERING (SSR)
Server-Side Rendering (SSR) is a method where the HTML of the page is generated on the server
instead of the client (browser). This approach contrasts with the typical Single-Page Application
(SPA) behavior, where the browser loads an initial HTML file and then dynamically fetches and
renders the content via JavaScript.
Here’s a brief breakdown of SSR and its benefits:
1. Rendering on the Server:
o Instead of fetching the data through AJAX calls and rendering it on the client, SSR
involves the server rendering the entire HTML page before sending it to the browser.
o When a user accesses a page (e.g., via a URL or refresh), the server sends a fully
rendered HTML page, which includes all the content, such as a list of issues, already
populated.
2. SEO Benefits:
o One of the primary advantages of SSR is that search engine crawlers can easily
index the content. Since search engines don’t typically execute JavaScript, they only
parse the raw HTML provided by the server.
o If the server sends a fully populated HTML document (not just a barebones page
waiting for JavaScript to populate), the search engine can index the content
effectively.
o For instance, if a page for "issues" is requested, the HTML returned by the server
should contain the list of issues in a table, not just a placeholder waiting for JavaScript
to load it.
3. First-Time Page Load:
o The first time a page is loaded (or when the user refreshes), the server sends the
complete HTML.
o Once the page is loaded in the browser, subsequent navigation within the app
(without reloading) can follow the SPA model, where React handles the rendering
client-side.
4. Challenges for SPAs:
o SPAs excel at providing a smooth and fast user experience once the initial page is
loaded. However, for content to be indexed properly, a SPA may not be enough
because it relies on JavaScript to render the content dynamically.
o SSR solves this problem by providing the content as static HTML right away,
ensuring both fast initial load times and SEO compatibility.
5. Hybrid Rendering:
o In some cases, applications use Universal or Isomorphic rendering, where the
application can either render on the client or the server, depending on the situation.
o With this approach, pages can be rendered server-side for better SEO and quicker
first-time load, while also allowing client-side rendering for a smooth navigation
experience in SPAs.
New directory structure
In the new directory structure, the goal is to better organize the project by splitting the source files
into three main directories:
1. src/:
o This will store shared React components that can be used across both the client-side
(browser) and server-side code.
o These components are common and will be used in both environments.
2. browser/:
o This directory will contain files and configurations specific to the client-side
(browser).
o For example, the App.jsx file, which is the entry point for the client-side bundle, will
be placed here. This is the file that gets bundled into a single JavaScript file and
served to the browser for execution.
3. server/:
o This directory will contain files that are specific to server-side code.
o For instance, uiserver.js (which would handle server-side rendering or other server
tasks) will be moved to this directory.
o These files will import the shared React components from the src/ directory to render
content on the server side.
Steps for Organizing the Project:
1. Create the new directories:
mkdir browser
mkdir server
2. Move the relevant files into these directories:
o Move App.jsx (client-side entry point) into the browser/ directory:
mv src/App.jsx browser/
o Move uiserver.js (server-side rendering script) into the server/ directory:
mv src/uiserver.js server/
3. Update the linting, compiling, and bundling configurations to reflect the new directory
structure:
o If you're using tools like Webpack or Babel, you'll need to update the configuration
files to correctly reference the new paths for client-side and server-side code.
Basic Server Rendering with React
In server-side rendering (SSR), React can generate the HTML on the server instead of the client.
This allows the server to send pre-rendered HTML to the browser, which is beneficial for SEO and
the initial load performance. The main difference between client-side rendering and server-side
rendering lies in the rendering process:
• Client-side rendering uses ReactDOM.render() to render a React component into the DOM.
• Server-side rendering uses ReactDOMServer.renderToString() to generate the HTML
string on the server.
Example: Basic About Component for SSR
1. Creating the About component: You can create a simple About component which will
display some content when rendered. This component is defined as follows:
// src/About.jsx
import React from "react";
export default function About() {
return (
<div className="text-center">
<h3>Issue Tracker version 0.9</h3>
<h4>All version 1.0</h4>
</div>
);
}
2. Include the About component in the application: To render this About component when
the "About" link is clicked, you need to modify your routing logic.
In the Contents.jsx (or wherever you define your routes), you can include the About component and
make it accessible through routing, like this:
// src/Contents.jsx
import React from "react";
import { Route, Switch } from "react-router-dom";
import About from "./About"; // Import the About component
function Contents() {
return (
<div>
<Switch>
<Route path="/about" component={About} />
{/* Other routes */}
</Switch>
</div>
);
}

export default Contents;


In this example:
o The About component will be displayed when the /about route is matched.
o The <Switch> component ensures that only the first matching route is rendered.
Server-Side Rendering Setup
For SSR, React on the server needs to render the component to a string that can be sent to the browser
as HTML. To do this, you use ReactDOMServer.renderToString():
// server/uiserver.js
import React from "react";
import ReactDOMServer from "react-dom/server";
import About from "../src/About"; // Import the About component
const html = ReactDOMServer.renderToString(<About />);
// Send the rendered HTML to the browser
The HTML generated by renderToString() is the full markup that will be returned to the client. For
a complete SSR setup, you also need to serve the initial HTML page and hydrate the React app on
the client side after it's loaded.
Webpack for the server:
• The need for Webpack for the server arises because manually compiling files like About.js
for server-side rendering (SSR) becomes impractical as the project grows.
• Instead of manually compiling each file, Webpack automates this process, allowing all the
files in the src directory to be bundled together for server-side use.
• Webpack can be used for both client-side and server-side JavaScript bundling. For the
server-side, it helps compile JSX files and maintain consistency across the codebase.
However, many server-side packages like Express dynamically import dependencies,
making it tricky for Webpack to bundle them.
• To solve this, third-party libraries are excluded from the Webpack bundle and rely
on node_modules. The webpack.config.js file can export multiple configurations for
client and server, allowing both to be bundled separately while handling dependencies
efficiently.
HMR for Server
• HMR for Server (Hot Module Replacement) in server-side development can improve
workflow by automatically updating modules without needing to restart the entire server.
• When using Webpack for server-side bundling, HMR is possible but challenging because
Express (or other server frameworks) stores references to existing modules.
Here's the approach to make HMR work for server-side code:
1. Limit HMR to shared modules: To simplify, only enable HMR for the shared modules (those in the
shared folder or used across both the client and server). For changes in uiserver.js, restart the server
manually because these changes are infrequent.
2. Create a new Webpack config for server HMR: The configuration for development HMR should be
different from the production bundle. The development config includes HMR setup to ensure updates to
the shared modules are dynamically reloaded.
Example:
Webpack Development Configuration for Server HMR:
Here’s an outline for the Webpack server config:
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: './server/uiserver.js', // Entry point for server-side code
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'server.bundle.js',
},
target: 'node',
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: 'babel-loader', // Transpile JSX or ES6
},
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // Enable HMR for server-side code
],
devServer: {
contentBase: path.join(__dirname, 'dist'),
hot: true, // Enable hot reloading
},
};

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy