Full Stack
Full Stack
Full Stack
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:
• 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.
• 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-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.
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.
• 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.
• React is available as a JavaScript library that can be included directly in the HTML file using
the <script> tag.
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.
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.
• 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():
type: Specifies the type of element, like 'div', 'span', or a custom component.
children: Any nested elements or text content. Multiple children can be passed as additional
arguments or as an array.
• 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>.
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
$ nvm install 10
→ installed Node.js, let's make that version the default for future
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
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.
• 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.
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.
• 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.
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>
);
…..
render() {
return (
<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:
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.
State in a Component:
);
const initialIssues = [
];
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.
constructor() {
super();
this.state = { issues: [] };
• 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).
async componentDidMount() {
const newIssues = await fetchIssuesFromServer(); // Assume this fetches the issues
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.
Example:
createIssue(issue) {
issue.id = this.state.issues.length + 1;
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).
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).
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:
// 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 }
];
// 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" });
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();
});
• 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.