[Go to site: main page, start]

0% found this document useful (0 votes)
2 views90 pages

Web Applications Development Notes

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views90 pages

Web Applications Development Notes

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

11

Web Applications Development

Figure 11.1 It takes many roles to build a responsive design in web applications development for multiple system applications.
(credit: modification of “190827-F-ND912-035” by Tech. Sgt. R. J. Biermann/Lt. Col. Wilson/U.S. Air Force, Public Domain)

Chapter Outline
11.1 Modern Web Applications Architectures
11.2 Sample Responsive WAD with Bootstrap and Django
11.3 Sample Responsive WAD with Bootstrap/React and Node
11.4 Sample Responsive WAD with Bootstrap/React and Django
11.5 Sample Native WAD with React Native and Node or Django
11.6 Sample Ethereum Blockchain Web 2.0/Web 3.0 Application

Introduction
TechWorks is creating several web applications this year for a new product line. One application is an AI-image
generator website and auction house for selling images. An outside consultant has been brought in, and they
have determined that a hybrid Web 2.0/3.0 architecture is best suited for this solution. However, the
engineering team who will perform the work needs to gain experience with Web 3.0 technologies. Therefore,
the consultant recommended that TechWorks take a popular internal desktop application for managing to-do
lists and re-create it as a hybrid Web 2.0/3.0-based application so engineers can gain practical experience with
various web application frameworks and technologies, with the added benefit of accessing their to-dos from
anywhere.

The TechWorks engineering team has decided to perform iterative releases of the to-do application, starting
with responsive web apps, as they will render well on various screen sizes, from large monitors to smaller
displays like phones and tablets. Next, they will employ a native web application framework to target specific
devices like Android and iPhones. Lastly, they will explore building a Web 2.0/3.0-based to-do application using
blockchain technology, as they believe this approach will give them the necessary skills for creating future
solutions.
566 11 • Web Applications Development

11.1 Modern Web Applications Architectures


Learning Objectives
By the end of this section, you will be able to:
• Understand the use of server-side rendering and MVC patterns
• Relate to the technology used to create responsive Web 2.0 applications
• Become familiar with the technology used to create native mobile applications
• Understand how to create Web 3.0 applications as well as hybrid Web 2.0/3.0 applications

The World Wide Web, or the Web as it is known today, started as a way to link content (primarily text and
images) stored on different servers or machines. It was invented by Tim Berners-Lee in 1989 while he worked
as a researcher at the European Organization for Nuclear Research (CERN), home to the European Particle
Physics Laboratory. Sir Tim Berners-Lee was knighted by Queen Elizabeth II in 2004 for his pioneering work. He
created the Hypertext Transfer Protocol (HTTP) that operates on top of Transmission Control Protocol/Internet
Protocol (TCP/IP), the principal protocols used on the Internet. Clients (web browsers) transmit HTTP requests
to a web server, which is a software application that runs at a Uniform Resource Locator (URL) that specifies a
location on the Web to access it, and responds by providing pages rendered in the hypertext markup language
(HTML). This simple request and response paradigm, a client-server model, was easy to implement and
allowed for the rapid growth of the Web. This phase of the Web, which began after 1989 and ended around
2004, would become known as Web 1.0, a period where the user’s interaction was limited primarily to reading
and selecting web pages. A web page is a document commonly written in HTML and viewed in a browser.
Figure 11.2 shows a simple Web 1.0 architecture and common usage. An encryption layer was later added to
the HTTP protocol, which resulted in creating the HTTPS protocol. This made it possible to protect the sharing
of sensitive information over the Web from eavesdropping attacks. While web servers only served web pages
initially, a Common Gateway Interface (CGI) was subsequently added after the initial implementation of web
servers to make it possible to link to applications via URLs on the Web.

Figure 11.2 This architecture outlines a user’s interaction with a Web 1.0 website. (attribution: Copyright Rice University, OpenStax,
under CC BY 4.0 license)

As the Web evolved from this basic architecture, the need for more dynamic and interactive experiences
became apparent. Users were no longer content with simply viewing static pages; they wanted to contribute
content and engage with other users. Also called online publishing, web publishing publishes content on the
Web while applying traditional publishing models. It was akin to digitizing an encyclopedia (images and text)

Access for free at [Link]


11.1 • Modern Web Applications Architectures 567

and putting it online with hyperlinks. Today, simple websites with limited functionality, such as early blogs or
static sites, still follow this model. A more interactive model that could scale to meet user demand was needed
to support users’ desire to provide content and interact with other users. A design pattern is a reusable
solution to a common software design problem. Figure 11.3 illustrates the Model-View-Controller (MVC) design
pattern that was employed to separate a traditional web application’s data model, presentation, and business
logic layers into its components.

Figure 11.3 This figure shows a user’s interaction with the Model-View-Controller pattern. (attribution: Copyright Rice University,
OpenStax, under CC BY 4.0 license)

The original implementation of the MVC pattern on the Web was such that the View would send requests to
the Controller and the Controller obtained data from the Model and rendered it within HTML pages that were
passed to browsers for presentation purposes. AJAX technology was later introduced to enable a more
complete implementation of MVC on the Web that allowed asynchronous updates to page components and
did not require refreshing pages in the browser to fetch data.

Following Moore’s law, which states that the number of transistors on an integrated circuit doubles roughly
every two years, the processing power of smaller devices like laptops, tablets, and mobile phones became the
preferred way users interacted on the Web. As Internet data transfer speeds and bandwidth increased through
better hardware, fiber-optic cables, and mobile wireless technology, the rendering of web applications’
interactive interfaces moved from the server side to the client side. This led to being able to run native
applications (apps) on mobile wireless phones that could take advantage of specific device rendering features.
In a paradigm shift that was opposite to web apps, the data model moved off the phone and onto remote
servers. These solutions led to a richer user experience known as Web 2.0, which is a phase of the Web
focused on social interactions. This phase started in 2004, and social media websites using Web 2.0, such as
Facebook (now Meta) and Twitter (now X), are well-known examples of this web phase of social interactivity.

The next phase of the web, Web 3.0, which is a phase of the Web where user activities may focus on
decentralized access to solutions and data, is seeing a shift from the more traditional client-server model to a
peer-to-peer networking model. A peer-to-peer (P2P) network is one in which devices connect and can share
data and processing without needing a centralized server. Peers in this scheme can perform the role of a
traditional client, server, or both. This shift fosters a trusted, decentralized, and open web, where large
companies do not own the data, but rather where data is collectively owned by users. The use of other
technologies like generative artificial intelligence (GenAI), which is powered by machine learning, aims to
568 11 • Web Applications Development

improve information access by mediating end-user searches to generate corresponding meaningful


information out of the content available on the Web. While the benefits of artificial intelligence and machine
learning are vast, enabling enhanced data processing and decision-making, it is equally important to consider
the risks. These technologies can pose ethical concerns, such as data privacy issues, biased algorithms, and
the potential for misuse, thus highlighting the importance of responsible development and implementation. In
particular, while GenAI technology is appealing and can be successful in some cases, GenAI is also known to
hallucinate and generate unpredictable and often inaccurate responses to web searches. The exemplar apps
of the Web 3.0 and later phases are still to be determined. Still, if the previous phases of the Web are any
indication, it will fundamentally change how we operate in an ever-evolving technological world.

Throughout this section, we will discover how the application architectures found in Web 2.0 apps, native
mobile apps, and Web 3.0 apps are designed.

GLOBAL ISSUES IN TECHNOLOGY

Importance of Internationalization and Localization in Frameworks


Web applications are used worldwide, and specific internationalization and localization requirements must
be observed to facilitate the creation of web applications that people all over the world can use. This can be
challenging. To meet internationalization and localization prerequisites, services and products must be
flexible to compete in international markets. This includes having the malleability to adapt to the cultural
needs of target markets around the world. In global markets, language barriers are just one
1
internationalization and localization issue that must be considered for web applications.

Server-Side Rendering and MVC Patterns


The Web transitioned from its 1.0 phase, where the primary usage was viewing content composed of text and
images, to its 2.0 phase of user interaction. As it evolved, three technologies dominated the Web’s
programming landscape, commonly referred to as the trifecta:

• hypertext markup language (HTML): a standard markup language used to describe the structure and
content of web pages.
• cascading style sheets (CSS): a standard style sheet language used to alter the presentation style of the
content found in HTML (or other markup languages).
• JavaScript (JS): a scripting language that adds interactivity to web content and server-side functionality.
Various other scripting languages and competing approaches were used prior to the adoption of
JavaScript.

The adoption of HTML was already a given on the Web, and with the introduction of CSS in 1996, a stronger
push for separating content and style was introduced so that the styling of content could be specified solely as
part of style sheets rather than HTML tags. Web pages at this time mostly consisted of static content, which
would be generated and delivered on the web server. Essentially, the user would select an action in their
browser that sent an HTTP request to the server such as the following:

• When clicking a hyperlink on a web page, the browser would send an HTTP GET request to the web server.
This request asked for a specific resource (such as a web page or an image), and the server would respond
by sending the requested data back to the browser.
• When filling out a form on a web page and clicking the submit button, the browser would send an HTTP
POST request to the server. This request included the data that was entered (like a username and
password), and the server processed it and responded accordingly.

1 To learn more, check out Lionbridge’s blog ([Link] post about globalization.

Access for free at [Link]


11.1 • Modern Web Applications Architectures 569

Essentially, the web server performed all the HTML content rendering on the server side, and the client (web
browser) would present what it received. The browser in this model acts as a thin client, as it has minimal
functionality. Figure 11.4 illustrates the components of a traditional Web 2.0 architecture using Java-based
technologies. Notice the shift in user interaction with the website compared with a Web 1.0 website. Also note
that users are able to interact with applications via an application server that can retrieve data from a database
or file system. This enables support for managing web sessions that allow navigation across multiple pages.

Figure 11.4 This illustrates a user’s interaction with a traditional Web 2.0 architecture. (attribution: Copyright Rice University,
OpenStax, under CC BY 4.0 license)

Many of the original web applications were stateless, meaning that prior requests had no bearing on future
requests. For example, it was not possible to create a shopping cart as part of a web session that would keep
track of the session and what was purchased on a site and maintain the state (i.e., content in this case) of the
cart. In contrast, a stateful application is software that maintains the state of an application over time, while
in the case of a stateless application, state is not maintained by the system and previous actions do not
impact future ones. Stateless applications are simpler and easier to implement and maintain but offer limited
functionality.

As previously mentioned, Web 2.0 was partly driven by user demand for more interactive functionality.
Interactivity requires maintaining some state (e.g., the web session and the content of the cart as per the
previous example), thereby increasing the system’s complexity. This increased the demands on the web server
for almost all the processing needed to generate and present the website content. Increased functionality led
to more complex systems, and a clear separation of responsibility between the website’s rendition, business
logic (i.e., the logic implemented as part of the web application), and persistence layers were needed to
improve the quality and performance of the website while leveraging engineering expertise in given domains.

As you learned in Chapter 10 Enterprise and Solution Architectures Management, the Model-View-Controller
pattern is tailored to address this separation of responsibility. In the MVC pattern, the Model is the persistence
layer responsible for data storage and retrieval. It has a well-defined API that the Controller uses. The View is
the presentation layer that handles the user interface. Finally, the Controller acts as the business logic layer
that performs processing and enforces rules to generate applicable content within a given application domain
and separates the user interface from the data. It also has a well-defined API that the View understands. The
best-practice design concept used to create software systems in a way that ensures weak associations with
other components is called loose coupling. This concept allows for separation of concerns between
components, which leads to maintaining high cohesion within websites’ functionalities. MVC components are
loosely coupled in that the various components can interact with one another to access the specific
570 11 • Web Applications Development

functionalities provided by each component. High cohesion ensures that everything that is needed to provide
a specific functionality is included in one of the components. For example, on a banking website, functionality
for deposits and withdrawals may be collocated on the server within the same component to ensure high
cohesion; however, features for applying for a loan may be located within another component. Three popular
server-side web application frameworks that implemented the MVC pattern were Apache Struts, [Link], and
Ruby on Rails.

CONCEPTS IN PRACTICE

APIs Play a Large Role in Web Services


Understanding APIs and their protocols helps determine which platform is being accessed and at what
level. APIs allow access to any software with a specific purpose or functionality. APIs can be used as
contracts between multiple applications.

How do APIs work? The API architecture is usually explained in terms of client and server. The application
sending the request is called the client, and the application sending the response is called the server. For
example, in the case of an API for a weather service, the weather service database is maintained on the
server side, and the mobile app is running on a client mobile device.

The server side performs the majority of the functionality. It uses a combination of templated HTML, controller
and application server technologies (e.g., [Link], C#), and SQL. JavaScript is sent to the browser using jQuery
for cross-browser support, or it may use Asynchronous JavaScript and XML to communicate with the web
server without refreshing the page. Asynchronous JavaScript and XML (AJAX) exchanges small amounts of
data between a client and server. The engineering team using such a web platform must understand and
enforce the separation of responsibilities between the MVC components to ensure future modifications,
especially significant changes, can be made without rearchitecting the system. Because the engineering team
needs to know different programming languages for different layers, there may be some internal resistance to
this, and it may be tempting to go around a layer to make a quick fix. Essentially, making sure that the
architecture of the web platform is understood and used properly, architectural adherence is predicated on
the expertise of the engineering team members and more on the nature of the tools used.

Responsive Web 2.0 Applications


By the mid-2000s, JavaScript became popular for client-side browser functionality. AJAX and jQuery
technologies allowed developers to create single-page applications (SPA). For the end user, SPAs offered
functionality like a traditional desktop application and drastically improved user experience by reducing
latency. No longer were expensive web server requests needed that resulted in full page refreshes in the
browser. Instead, small data transmissions could be sent and received between the browser and server
through AJAX. Figure 11.5 compares the life cycle of SPAs to a traditional Web 2.0 application.

Access for free at [Link]


11.1 • Modern Web Applications Architectures 571

Figure 11.5 This is a comparison of the life cycles between traditional Web 2.0 applications and SPAs. (attribution: Copyright Rice
University, OpenStax, under CC BY 4.0 license)

LINK TO LEARNING

The World Wide Web Consortium (W3C) ([Link] develops standards and guidelines
for the Web. You can discover more about them and examine some of their current draft standards.

jQuery, an open-source JavaScript library, ensured that web developers could write JavaScript for a generic
browser document object model (DOM) that would run regardless of the user’s browser. The DOM is a
programming interface provided by browsers. It allows scripts, written in JavaScript for example, to interact
with the structure of a web page. When a web page is loaded into the browser, the browser creates a DOM of
the page. The DOM structure is a hierarchical treelike structure that organizes the elements of the page as
objects. The model used by the DOM enables dynamic access and facilitates the manipulation of content,
structure, and style of web pages. Figure 11.6 illustrates a typical SPA architecture where a single web page is
delivered to the browser. Note that in this model, the user’s interaction with the site has increased in the
amount of content generated by the user.
572 11 • Web Applications Development

Figure 11.6 This illustrates a user’s interaction with a single-page application (SPA). (attribution: Copyright Rice University, OpenStax,
under CC BY 4.0 license)

The more sophisticated SPAs required large amounts of JavaScript on the client side. Many end users had
underpowered machines or out-of-date web browsers, and the SPAs performed poorly.

In the early 2010s, web application frameworks were introduced to create complex, client-side web
applications that performed well, gave a native desktop application-like experience, and were easier for
developers to create. These applications followed a Model-View-ViewModel (MVVM) pattern. Figure 11.7
illustrates the relationship between the View, ViewModel, and Model components.

Figure 11.7 Various data binding, events, and actions occur between the components of the Model-View-ViewModel pattern.
(attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

This pattern is like the MVC pattern we’ve previously explored; however, several key differences exist. The
following are some of the similarities and differences:

• The View is responsible for the presentation and only interacts with the ViewModel. This is similar in
responsibility to the View role and interaction with the Controller in the MVC pattern. The View here binds
to functions and properties in the ViewModel and receives notifications on operations and changes to the
data. It doesn’t interact directly with the Model.
• The Model is similar to the Model in the MVC pattern and is responsible for data retrieval and storage. It
doesn’t know anything about the ViewModel.
• The ViewModel is similar to the Controller in that it decouples the relationship between the View and
Model and handles data manipulation. The ViewModel responds to notifications from the Model and will
send events to the View if needed. Because the View binds to the ViewModel, the ViewModel doesn’t know
anything about the View. The ViewModel can work with a local Model in the browser, a remote Model, or

Access for free at [Link]


11.1 • Modern Web Applications Architectures 573

both.

Unlike the previous MVC pattern regarding server-side rendering, the MVVM pattern is run entirely in the
client. A Representational State Transfer (REST) API decouples the client-side Model and ViewModel
components from the server-side business logic and persistence store. REST-based (aka RESTful) APIs follow
the architecture style designed for the Web. These APIs use the JavaScript Object Notation (JSON) file format
that represents data as text-based attribute-value information. Figure 11.8 illustrates the MVVM pattern as it
applies to an SPA.

Figure 11.8 This illustrates the Model-View-ViewModel pattern as applied to the SPA architecture. (attribution: Copyright Rice
University, OpenStax, under CC BY 4.0 license)

As you can see from the diagram, this model is more complex than the simpler MVC pattern. The quality of the
APIs partly determines the effectiveness of this pattern. REST-based APIs benefit from being discoverable (i.e.,
all API URIs can be found from the root API node) and should be versioned (i.e., to keep track of changes to
interfaces for compatibility purposes) so that upgrades don’t break API users. Without API versioning, coupling
between client and server increases (due to semantic and syntactic coupling), and upgrades become costly.
Similar to a URL, a Uniform Resource Identifier (URI) is a string of characters that identifies a resource on the
Web.

Regardless of these flaws, early browser-based frameworks proved the value of creating rich client-side apps.
Web standards evolved, and newer frameworks emerged that adhered to the newer standards and solved
many of the problems of their predecessors. Popular SPA frameworks include Angular, [Link], React, and
[Link]. These are often used in conjunction with server-side tools, creating a “full stack” of technologies for
developing the solution. A popular server-side technology in this stack is Node, a runtime environment for
executing JavaScript code.

Approaches to minimizing the data transferred between the APIs and the client to reduce network traffic or
simplifying access to the data resulted in two primary approaches. One was flattening the data model. Instead
of returning data in a nested format (such as from a relational database), the returned data would be
“flattened” to a series of key-value pairs, each resulting in a unique return value. If the specific request could
be made, the flattened data would be preferred to navigating the nested data to improve performance.
However, creating APIs to fit specific requests could be challenging. Another solution was using GraphQL, an
open-source query and manipulation language. With GraphQL, callers of its API could craft specific requests to
return only the needed data, which made access to many services such as the ones provided by microservices
574 11 • Web Applications Development

architectures more scalable.

THINK IT THROUGH

Framework Selection
Given that many web and native application frameworks are available today, is there a process that
facilitates the selection of these frameworks?

Native Mobile Applications


Native mobile applications are designed to run on specific mobile operating systems (i.e., Android, iOS).
Android and iOS operating systems dominate the mobile device market. In 2023, Android had approximately
70% of the worldwide market share, with iOS at around 29%. Samsung, KaiOS, Windows, Linux, and others
2
make up the remaining 1% of the market.

However, in the United States in 2023, iOS was the predominant OS with roughly 61% of the market and
Android at 38%. Here, we’ll look at the specifics of native mobile app development by focusing on Android and
3
iOS.

Native Application Development for Android


Native application development takes advantage of the specific features available on mobile devices. The
creators of the Android operating system (OS) originally designed it as an OS for digital cameras; however, they
soon pivoted and changed it to be an OS for smartphones. Today, the Android OS runs on most mobile devices
worldwide. It can be found on the Google Pixel, Samsung, OnePlus, and other phones.

Developers for Android mobile apps have a rich ecosystem composed of development tools, programming
languages, training, and services. The primary developmental tools are:

• Android Studio is the official IDE for Android development, built off JetBrains’ IntelliJ IDEA software.
• Jetpack Compose is a toolkit for building native user interfaces (UI).
• Firebase is an app development platform and a collection of services for authenticating users, integrating
ads, running A/B tests, and more. Firebase includes an A/B testing tool that helps test changes to web
apps to see how changes impact key metrics such as revenue and customer retention. Developers will
likely write software in Java, Kotlin, or C++. Java was historically the primary language for Android
development. It runs on the Java Virtual Machine (JVM), which allows for creating platform-independent
software. Kotlin is the preferred Android development language. It runs on the JVM but also runs on the
Android Native Development Kit (NDK), which is used for performance-critical parts of applications. The
NDK performs better than the JVM, and it provides direct access to physical device components (e.g.,
sensors and touch screen). C and C++ code can also run on the NDK.

Applications developed for Android are distributed through App Stores. Google Play is the principal app store,
but others include Amazon Appstore, HUAWEI AppGallery, and Samsung Galaxy Store.

LINK TO LEARNING

To explore Android app development further, Google offers free training. You can get started by creating
your first “Hello World” ([Link] Android program.

2 Statcounter Global Stats, “Mobile Operating System Market Share Worldwide, Dec 2022–Dec 2023,” January 2, 2024.
[Link]
3 Statcounter Global Stats, “Mobile Operating System Market Share United States Of America, Dec 2022–Dec 2023,” January 2, 2024.
[Link]

Access for free at [Link]


11.1 • Modern Web Applications Architectures 575

Native Application Development for iOS


Apple’s iPhone was released in 2007 and quickly dominated the mobile phone market in the United States due
to its simple, intuitive touch screen interface based on the success of its music player, the iPod, contributed to
its popularity. The iOS operating system runs Apple’s device ecosystem, which includes iPhones, Apple TVs,
Apple Watches, and more.

Xcode is the primary IDE used for all Apple device development. Developers will code in Objective-C or Swift.
Objective-C was the primary development language for iOS; however, it was challenging to learn. In 2014,
Apple released the Swift programming language specifically designed for iOS development. It offers high-
order language features, making it easier to develop software and built-in memory management, which
makes less prone to crash.

INDUSTRY SPOTLIGHT

Framework Selection Based on Industry


Native application frameworks are important in every industry today. For example, mobile health
applications have become quite popular. Smartwatches can collect health-related data using various
sensors and mobile health applications can leverage that data to provide useful reports to users as they
exercise. Using a native application framework provides quicker load times, smooth animations and
transitions, optimal security, and a seamless user experience, to make it easier to immediately track and
access health-care data.

Drawbacks to using native application framework include a longer development process, increased cost,
complex maintenance and updates, platform dependency, regulatory and compliance issues, and end-user
barriers.

The Benefits and Drawbacks Between Native, Web, and Hybrid Mobile Application
Development
Native applications have the benefits of accessing device-specific hardware and sensors (e.g., camera,
accelerometer), data (e.g., location, contacts), and are optimized for performance.

However, they have the drawbacks of being device-dependent and available primarily through proprietary app
stores (Google Play for Android and Apple’s App Store for iOS). Developers need to learn different languages
and libraries for the devices. However, cross-platform development is possible with frameworks (e.g., Flutter,
Kotlin Multiplatform Mobile), allowing developers to code in a single language and run solutions on both
platforms.

Web apps can also run in a browser on mobile devices. They have the distinct advantage of responsiveness
and can run on various screen sizes—thus allowing for a single codebase that can increase productivity and
reduce cost. Disadvantages to web apps on mobile devices are limited access to hardware and software
features, lower performance than native apps, and web apps may perform differently depending on the
mobile browser. Traditionally, web apps didn’t look like native apps. In 2017, Google introduced Progressive
Web Apps for Android, allowing web apps to look and feel similar to native apps.

Finally, hybrid apps are web apps wrapped inside a native device framework (e.g., Apache Cordova). These
apps have the advantages of using traditional web application development while accessing and utilizing
device functions and running on multiple mobile platforms. The drawbacks are reduced speed and potential
security vulnerabilities found in the framework.
576 11 • Web Applications Development

CONCEPTS IN PRACTICE

Software Patterns and Frameworks


As discussed in Chapter 9 Software Engineering and Chapter 10 Enterprise and Solution Architectures
Management, architectural styles, architectural patterns, and design patterns are typically used to enforce
the quality attributes of software solutions. To facilitate the creation and maintenance of web applications
and scalable transactional websites, web application frameworks and native application frameworks that
leverage applicable patterns, such as MVC, were created and improved over the past couple of decades.
Web frameworks are used within web application frameworks to facilitate the use of HTML5, CSS3, and
JavaScript and to publish responsive web pages that can be rendered by modern browsers on all modern
target devices. Web application frameworks help process UI-driven requests that result in publishing or
updating web pages. Native application frameworks take advantage of capabilities available on specific
target devices such as iPhones and Android phones. Organizations in many industries rely on web
applications and related frameworks to conduct business daily.

Web 3.0 Applications


Web 3.0 is the next phase of the Web. It is still being realized, and similar to Web 1.0 and 2.0, it can only be
fully understood in hindsight. The technology and uses of the Web overlap between the phases, with newer
phases becoming preferred over their predecessor phases. If Web 1.0 was the read-only web, and Web 2.0 was
the participation (write) web, then Web 3.0 may be the read, write, and execute web.

Tim Berners-Lee had referred to Web 3.0 as the Semantic Web, a system of autonomous agents, which are
software programs that respond to events. That model has shifted over the years. While AI (and other
technologies such as AR/VR) will likely form a part of Web 3.0 or Web x.0, the principles that govern the next
phase are expected to be around a web that is decentralized, permissionless, and trusted.

Web 3.0 sees a shift from the more traditional client-server model to a peer-to-peer networking model. A peer-
to-peer network is one in which devices connect and can share data and processing without needing a
centralized server. Peers in this scheme can perform the role of a traditional client, server, or both. This shift
will foster a trusted, decentralized, and open web, where large companies don’t own the data, but everyone
collectively owns it. Technologies such as a smart contract allow a trusted model that is needed in a
decentralized system. Artificial intelligence and machine learning will improve information access through
understanding the meaning of content available on the Web. The exemplar apps of the Web 3.0 phase will be
defined in the future. Still, if the previous phases of the Web are any indication, it will fundamentally change
how we operate in an ever-evolving technological world.

Finally, Web 3.0 apps will run on a web that supports Web 1.0 and 2.0 apps, with the likely result being hybrid
architectures that are partially Web 2.0 and 3.0.

Web 3.0 Application Architectures


Web 3.0 apps are architected without a centralized server, so they are considered to be decentralized Apps
(DApps), which are applications that execute smart contracts and run over distributed ledger technology (DLT).
Smart contracts are programs that can be executed on a distributed ledger. Distributed ledgers use
independent network nodes to record, share, and synchronize transactions in their respective electronic
ledgers instead of keeping them in a centralized server. The code is visible to all parties, and trust is put into
the code instead of a centralized third party. Distributed ledgers chronicle transactions between accounts that
are recorded in multiple places. Blockchain is a type of DLT.

Let’s compare a traditional Web 2.0 application with a 3.0 DApp. In Web 2.0, if you created a website for users
to post pictures and make comments on them, you would need functionality for authenticating users,

Access for free at [Link]


11.1 • Modern Web Applications Architectures 577

authorizing their actions, generating a UI for adding images, browsing images, and posting comments. To do
this, you would need a front-end web server and back-end processing for business logic and data storage.
These servers would run in a company’s data center or on a cloud provider. The company would own all the
code and data, including metadata about how you interact with the website (e.g., what you commented on,
how long you looked at a picture). As a reminder, Figure 11.4 illustrates a traditional Web 2.0 architecture (note:
for our purposes, the SPA architecture could also be used here).

In a Web 3.0 DApp, the functionality for creating an application for posting pictures and commenting on them
would remain the same. The principal differences would be where the code runs and who owns the code and
data. Let’s break this down into a series of steps that shift away from a centralized solution to a distributed
one.

To start, we can keep the web server’s front end and replace the back-end code with the distributed
application. The Ethereum blockchain, as an example, is a deterministic state machine that runs on a peer-to-
peer network. A deterministic state machine has a model of computation that relies on a finite number of
states and transitions between them to respond to inputs. It guarantees a single transition from one state to
another in response to an input. Because it is based on a deterministic state machine, the Ethereum
blockchain is often referred to as a “world computer.” Ethereum blockchain transactions are calls to methods
that are implemented in smart contracts. These method calls result in change to the data (aka, state) that is
maintained by the contracts within the blockchain. The Ethereum blockchain records transactions into blocks
that are added to its blockchain. Changes to the state machine itself (e.g., modify the block or transaction data
structures used in the Ethereum blockchain) require consensus between the node providers that support the
peer-to-peer blockchain network. Anyone in the world can read or write to the machine—a central authority
does not govern it.

Smart contracts form the code and are written in high-level languages like Solidity or Vyper. The high-level
contract code is compiled into bytecode that can be executed on the Ethereum Virtual Machine (EVM). Each
block contains a hash pointer of the previous block, with a time stamp and the transaction data. The hash
pointer includes a cryptographic hash (i.e., a fixed-size digest of the previous block that makes it possible to
verify that the previous block was not changed since it was stored in the blockchain; the cryptographic part
ensures that the hash value has some special properties and, in particular, that the original data cannot be
derived from the hash value).

Figure 11.9 replaces the traditional back-end components of a website with a blockchain. The user’s interaction
with the website is consistent with a traditional Web 2.0 website, as the back-end processing is hidden from
the user, though it has been replaced with a blockchain node.
578 11 • Web Applications Development

Figure 11.9 Here is a traditional Web 2.0 website with back-end components replaced with a DApp. (attribution: Copyright Rice
University, OpenStax, under CC BY 4.0 license)

In the figure, the web server talks to a node of the blockchain, referred to as a full node. A full node is a
computer that maintains a copy of the blockchain and runs blockchain software. Operating a full node can
become expensive because you need to provide the hardware and pay a fee to join the Ethereum network.
Blockchain end users typically use a software wallet such as MetaMask to access nodes in the blockchain or
use a third-party wallet offered by providers like Infura, Alchemy, or QuickNode. MetaMask is a wallet
technology that stores a user’s private keys in their browser.

Blockchain providers use the JSON-RPC specification for managing communication from clients/end users. This
remote procedure call (RPC) is lightweight and transport agnostic.

As previously mentioned, any client can access the blockchain via a wallet provider, which requires creating an
account and obtaining a wallet ID. Once logged into their wallets, clients can perform blockchain transactions,
which end up reading and/or writing to the blockchain and changing the state of smart contracts. The wallet
ID is used to sign transactions so they can be traced to the client wallet. In our example, browsing photos on
the Web 3.0 application is a read transaction that would not require signing anything; however, adding photos
and comments would.

Adding data to the blockchain incurs a cost as nodes now need to store that data. The user incurs this
expense. Imagine paying every time you upload a photo to your favorite social media app. Instead of storing
the data on the blockchain, a cost-effective approach would be to store the data using the InterPlanetary File
System (IPFS) protocol. IPFS is a peer-to-peer distributed file-sharing protocol. You can go through a provider
like Pinata to get a hash value for the data (i.e., a fixed length digest of the data that cannot be used to obtain
the original data) you upload to the IPFS and store that hash value in the blockchain via a smart contract
interface, thereby reducing the storage cost of data within the blockchain.

Figure 11.10 shows the addition of:

• the provider between the web server and the DApp


• a signer for when the user wants to write to the application

Access for free at [Link]


11.1 • Modern Web Applications Architectures 579

• the inclusion of the IPFS for data storage

Figure 11.10 This architecture has added a signer, provider, and IPFS. (attribution: Copyright Rice University, OpenStax, under CC BY
4.0 license)

Up to this point, we’ve kept the front-end logic on a web server hosted in a centralized location. This is a good
temporary approach for an organization that wants to transition a legacy solution to a DApp over time.
Because IPFS will host some of the data of the DApp, let’s move the front-end HTML, CSS, and JavaScript there
and load it into the browser like an SPA app.

Like an SPA, we want the application to run asynchronously and respond to events (like changing data) as they
occur. [Link] is a JavaScript library that uses the JSON-RPC to respond to events fired when smart contracts
execute. Alternatively, The Graph is a solution that uses GraphQL to make it easier to query data on the
blockchain.

Figure 11.11 shows the updated architecture with the front-end residing in IPFS and the addition of The Graph
(listed as GraphQL) for improved querying of the blockchain.
580 11 • Web Applications Development

Figure 11.11 The front-end web page has been moved to IPFS, and graphing query capabilities have been added. (attribution:
Copyright Rice University, OpenStax, under CC BY 4.0 license)

This results in a Web 3.0 application; however, there are problems with this architecture that we will examine
next.

Web 3.0 Application Challenges


Blockchains currently have a scaling problem. The average size of a block has increased over the years, and
transaction fees are associated with each transaction. A common fee is the gas price, which is the cost of
validating transactions and updating ledgers. Additionally, negative performance can occur on a blockchain
with large amounts of transactions.

One approach to help with scaling is the use of sidechains. A sidechain is a secondary (i.e., level 2 or L2)
blockchain that increases the blockchain network performance by aggregating transactions off-chain (i.e., off
the mainnet/Ethereum network) and committing them to the mainnet at once. Polygon is a popular L2 scaling
system for sidechaining. Other L2 scaling techniques include blockchain rollups, which are protocols designed
to enable high throughput and lower costs. They address scaling by bundling transactions and reducing data
sizes to increase transaction efficiency and limit storage costs. Examples of blockchain rollups include
optimistic and zero-knowledge rollups. An optimistic rollup is a protocol that increases transaction output by
bundling multiple transactions into batches, which are processed off-chain. In this case, transaction data is
recorded on the mainnet via data compression techniques that lower cost and increase transaction speed.

Access for free at [Link]


11.1 • Modern Web Applications Architectures 581

Optimistic rollups on Ethereum can improve scalability by a factor of 10 to 100. A zero-knowledge rollup (zk-
rollup) is a protocol that bundles transactions into batches that are executed off the mainnet. For every batch,
a zk-rollup operator submits a summary of required changes once the transactions in the batch have been
executed. Operators have also produced validity proofs that demonstrate that the changes are accurate. These
proofs are significantly smaller than transaction data so it is quicker and cheaper to verify them. Additionally,
zk-rollups are used on Ethereum to reduce transaction data size via compression techniques, which ends up
reducing user fees.

Figure 11.12 shows the addition of sidechains to the architecture to mitigate some of the challenges
associated with Web 3.0 DApps. Notice how the user’s interaction with the Web 3.0 app has grown from mostly
reading content in a Web 1.0 model to more fully participating in the content and functionality of the Web 3.0
app.

Figure 11.12 The user’s interaction with the full Web 3.0 application is highlighted here. (attribution: Copyright Rice University,
OpenStax, under CC BY 4.0 license)

As you can see, the architecture has become rather complex to support DApps effectively. However, Web 3.0 is
still in a nascent phase, and currently there are several solutions and tools being developed to make building
and deploying Web 3.0 DApps even easier. Hardhat is a developer ecosystem for building and deploying smart
contracts on a local network for testing.
582 11 • Web Applications Development

This architecture focused on blockchains and used Ethereum as the principal implementation. However, there
are other DLT solutions. Hashgraph is an approach where only selected nodes store the entire blockchain, and
voting mechanisms are introduced to validate if the blocks are correct. Stacks is another DLT where only the
smart contracts are decentralized, and the data is controlled by its owner. Owners can share or remove
it—ensuring data privacy.

TECHNOLOGY IN EVERYDAY LIFE

Use of Frameworks
Web applications are used today to power commercial websites that are accessed by people to complete
online transactions to buy goods of any kind. Mobile web applications and native versions of such are also
available on smartphones and watches to help do the same. How does using web and native application
frameworks help people in everyday life? Provide a couple of illustrative scenarios to explain your opinion.
Your scenarios should not be limited to describing how the frameworks are used, but rather describe
situations where these frameworks are applied in real life.

Hybrid Web 2.0/3.0 Applications


Due to the qualities and limitations of Web 2.0 and 3.0 architectures, it is likely that we’ll see solutions that are
a combination of the two approaches and leverage their best attributes. One way to do this would be to have
workflow processes that require a high rate of change implemented in a Web 2.0 architecture, while processes
that would benefit from using a distributed ledger being executed in Web 3.0. For example, traditional
commercial websites can keep using the Web 2.0 architecture, while payment solutions can be extended by
accessing the Web 3.0 architecture to make payments using cryptocurrencies (e.g., Bitcoin).

Let’s consider an app for generating AI artwork. Many solutions exist today for doing this; however, we want
our app to give “ownership” to the digital artwork a person generates. AI models are trained to recognize
existing artwork (e.g., paintings available via the [Link] API) that may be copyrighted—so ownership is still
being determined in the courts. Here, the term ownership is used to attribute AI image creation and nothing
more. While AI models are very popular, some companies do not want to share data with AI model creators
and prefer to have the AI models deployed in their own infrastructure to ensure full privacy. A non-fungible
token (NFT) is a unique digital identifier on a blockchain that a user may want to create of their image and
possibly sell (i.e., transfer ownership) on a marketplace. A common use case for this app might be:

1. A user logs in to the website and enters a prompt to generate an image.


2. After several rounds of adjusting their prompts, they end up with an image they want.
3. The user pays to have a non-fungible token created of the image, which is stored on a blockchain
marketplace for sale.

As you can imagine, running an AI image generator on a blockchain might not perform well. Likewise, creating
NFTs without blockchain technologies is counterintuitive. Therefore, the architecture for this solution needs to
encompass both Web 2.0 and 3.0 approaches.

Figure 11.13 shows how the APIs will do the heavy lifting of working with the AI model to generate the
artwork. Once the user is satisfied, they will interact with aspects of the UI that execute smart contracts to
generate and add the NFT to the blockchain. Transactions will happen on the blockchain. APIs may interact
directly with the blockchain, looking for similar works.

Access for free at [Link]


11.1 • Modern Web Applications Architectures 583

Figure 11.13 This outlines the user’s interaction with a hybrid Web 2.0/3.0 application. (attribution: Copyright Rice University,
OpenStax, under CC BY 4.0 license)

This model still has a centralized Web 2.0 server for artwork generation and account management; however,
portions that deal with NFT ownership and selling of that ownership are managed within the Web 3.0
blockchain infrastructure. This approach serves the needs of many businesses that want to take advantage of
Web 3.0 features while preserving their original Web 2.0 websites.

LINK TO LEARNING

This timeline showing the history of web frameworks ([Link] shows


numerous frameworks as well as some of their updates.
584 11 • Web Applications Development

11.2 Sample Responsive WAD with Bootstrap and Django


Learning Objectives
By the end of this section, you will be able to:
• Create a Todo web application with Bootstrap and Django
• Create a Django project
• Create and register a Todo app
• Define the Todo model
• Set up the Django REST APIs
• Create the user interface

In this module, you will create a simple, responsive Todo application. To accomplish this, you will use Bootstrap
and Django. Bootstrap is an open-source, responsive web application framework, and Django is a Python-
based web application development framework. Both frameworks are highly popular due to their ease of use.

Creating a Todo Web Application with Bootstrap and Django


The Todo web application in this subsection uses Bootstrap and Django. Bootstrap’s CSS templates are used
for the UI features. Django serves as both the front end and back end. Django templates are part of the user
interface to get and set data via HTTP requests. Incoming requests are then handled by an API built using the
Django REST Framework.

Prerequisites
To build the Todo application, you must install Python, PIP, Django, Django REST Framework, Bootstrap, and
jQuery. The Todo application on the following pages was developed and tested with specific software versions.
To avoid errors, please ensure you install the same versions: Python v3.9.4, PIP v21.3.1, Django v4.0.1, Django
REST Framework v3.13.1, Bootstrap v4.5.0, and jQuery v3.5.1.

The steps to build the Todo application are as follows:

• Install and set up a local programming environment for Python 3.


• Download and install Python 3.9.4.
• Figure 11.14 shows adding Python and its Scripts subfolder to your path environment data (on Windows,
the path updates might be: C:\Users\your_username\AppData\Local\Programs\Python\Python39 and
C:\Users\your_username\AppData\Local\Programs\Python\Python39\Scripts).

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 585

Figure 11.14 This is what appears when adding Python and its Scripts folders to the environment variables path on Windows.
(Used with permission from Microsoft.)

• Create a Python venv:


$ python -m venv py394venv
• Activate the venv:
$ cd py394venv
Windows: $ .\Scripts\[Link]
macOS: $ source ./bin/activate
• Install in the local programming environment Django:
$ pip install Django==4.0.1
• Install in the local programming environment Django REST Framework:
$ pip install djangorestframework==3.13.1]

Figure 11.15 shows the sequence of steps needed to install the Python environment for working with Django
and the Django REST Framework.
586 11 • Web Applications Development

Figure 11.15 This screenshot displays the sequence of steps needed to install the Python environment. (Used with permission from
Microsoft)

Creating the Django Project


The first step to building a Django web application is to create a Django project, which is a high-level directory
used to contain the directories and files necessary to run a Django web application. To create a Django project,
run the following commands:

$ mkdir BootstrapDjangoToDoApp
$ cd BootstrapDjangoToDoApp
$ django-admin startproject ToDoApp.

The period at the end of the last command is very important to ensure that Django-dependent files are
generated in the current directory. By following these commands, the directory, BootstrapDjangoToDoApp/,
will be created and Django-dependent files will be generated as shown in Figure 11.16.

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 587

Figure 11.16 The directory BootstrapDjangoToDoApp/ includes these Django-dependent files. (rendered in Django, a registered
trademark of the Django Software Foundation; attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

Django built-in database tables are used to manage users, groups, migrations, and so forth in a web
application. To generate these tables, run the migrate command:

$ python [Link] migrate

The final step to creating a Django project is to confirm that the setup was completed. To do this, run the
runserver command shown here:

$ python [Link] runserver

To further confirm that the Django project setup was completed, launch a browser and navigate to
[Link] Figure 11.17 shows the Django page.

Figure 11.17 Once the Django project setup is successfully completed, this page should appear at [Link] (credit:
Django is a registered trademark of the Django Software Foundation.)
588 11 • Web Applications Development

LINK TO LEARNING

Django ([Link] is a free and open-source Python web framework that can make
web development more efficient and less time-consuming. With an emphasis on streamlining web
development and making it easier for web developers to meet deadlines, Django also requires less code.

Creating and Registering the Todo App


Once the Django project is successfully completed and set up, the next step is to create the Todo application
and register it in the Django project. To accomplish this, run the following command:

$ python [Link] startapp todo

The todo/ directory will be generated under the Django project directory, BootstrapDjangoToDoApp/. Files
related to the Todo application will be generated as shown in Figure 11.18.

Figure 11.18 This shows the todo/ directory, which is generated under the Django project directory, BootstrapDjangoToDoApp/.
(rendered in Django, a registered trademark of the Django Software Foundation; attribution: Copyright Rice University, OpenStax,
under CC BY 4.0 license)

Next, the Todo application must be registered in the Django project as an installed app so that Django can
recognize it. To do this, open the ToDoApp/[Link] file. Look for the INSTALLED_APPS variable as seen in
Figure 11.19. Add ‘todo’ to the list as shown. Because the Django REST Framework will be used, also add
‘rest_framework’ to the list.

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 589

Figure 11.19 To register the Todo application in the Django project as an installed app, the list of installed apps should include
‘rest_framework’ and ‘todo’. (rendered in Django, a registered trademark of the Django Software Foundation; attribution: Copyright
Rice University, OpenStax, under CC BY 4.0 license)

Define the Todo Model


Once you register and install the ToDo web application, you will be able to create todo tasks, which can be
assigned categories. The next step is to create the models. Two models will be created for Category and
TodoList. Open the todo/[Link] file and add the code shown.

# -*- coding: utf-8 -*-


from __future__ import unicode_literals

from [Link] import models


from [Link] import timezone

# Create your models here.


class Category([Link]):

name = [Link](max_length=100)

class Meta:
verbose_name = ("Category")
verbose_name_plural = ("Categories")

def __str__(self):
return [Link]

class TodoList([Link]):
title = [Link](max_length=250)
content = [Link](blank=True)
created = [Link](default=[Link]().strftime("%Y-%m-%d"))
due_date = [Link](default=[Link]().strftime("%Y-%m-%d"))
category = [Link](Category, default="General",
on_delete=models.DO_NOTHING)
class Meta:
ordering = ["-created"] # order by most recently created
def __str__(self):
return [Link]
590 11 • Web Applications Development

The Category and TodoList Python classes describe the properties for the models for Category and TodoList
tables, respectively. The TodoList model contains a ForeignKey field to the Category model. Each todo item will
be associated with one category. After creating the models, a migration file needs to be generated to create
the physical tables in the database. To generate the migration file, run the following command:

$ python [Link] makemigrations todo

This command will generate a migration file in todo/migrations/, which will look like the following code.

# Generated by Django 4.0.1 on 2022-01-30 21:14

from [Link] import migrations, models


import [Link]

class Migration([Link]):

initial = True

dependencies = [
]

operations = [
[Link](
name='Category',
fields=[
('id', [Link](auto_created=True, primary_key=True,
serialize=False, verbose_name='ID')),
('name', [Link](max_length=100)),
],
options={
'verbose_name': 'Category',
'verbose_name_plural': 'Categories',
},
),
[Link](
name='TodoList',
fields=[
('id', [Link](auto_created=True, primary_key=True,
serialize=False, verbose_name='ID')),
('title', [Link](max_length=250)),
('content', [Link](blank=True)),
('created', [Link](default='2022-01-30')),
('due_date', [Link](default='2022-01-30')),
('category', [Link](default='General',
on_delete=[Link].DO_NOTHING, to='[Link]')),
],
options={
'ordering': ['-created'],

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 591

},
),
]

The next step is to apply the changes in the migration file to the database, which is accomplished by running
the following command:

$ python [Link] migrate

For this application, Django uses the default sqlite3 (db.sqlite3) database. Please note that Django supports
other databases as well, including MySQL and PostgreSQL. To define the Todo model, you can use the default
Django admin interface to perform CRUD operations on the database. To use the admin interface, open the
todo/[Link] file and register the models as seen in the following code snippet.

# -*- coding: utf-8 -*-


from __future__ import unicode_literals

from [Link] import admin


from . import models

# Register your models here.


class TodoListAdmin([Link]):
list_display = ("title", "created", "due_date")

class CategoryAdmin([Link]):
list_display = ("name",)

[Link]([Link], TodoListAdmin)
[Link]([Link], CategoryAdmin)

The next step is to create a superuser account that allows access to the admin interface. To do this, run the
following command and follow the prompts to enter a username, email address, and password for the
superuser.

$ python [Link] createsuperuser

Once this step is complete, restart the server using the following command:

$ python [Link] runserver

After this is complete, open a browser and navigate to [Link] To access the admin
interface, log in with the credentials that you set up for the superuser. When you log in to the admin interface,
you should see the following page from Figure 11.20. On this page, you will have the ability to create, edit, and
delete categories and todo items.
592 11 • Web Applications Development

Figure 11.20 The admin interface is where superusers can create, edit, and delete categories and todo items in the Todo web
application. (rendered in Django, a registered trademark of the Django Software Foundation; attribution: Copyright Rice University,
OpenStax, under CC BY 4.0 license)

Setting Up the Django REST APIs


Previously, you installed the Django REST Framework, which provides a toolkit to build APIs. In this section,
you’ll create the serializers, View functions, and routers required for the API.

Creating the Serializers


The next step is to implement two serializers, one for the Category model and one for the TodoList model. A
serializer is a tool to control response outputs and convert complex data into content, such as JSON. In the
todo/ directory, create the file, [Link], and add the code shown in the code snippet that follows. The
serializer classes inherit from [Link] because this class creates the serializer, with fields
corresponding to the Model fields defined earlier. Each serializer specifies the Model to work with and the
fields to be included in the JSON object, which are all fields.

# todo/[Link]

from rest_framework import serializers


from .models import TodoList, Category

class CategorySerializer([Link]):
class Meta:
model = Category
fields = "__all__"

class TodoSerializer([Link]):
class Meta:
model = TodoList
fields = "__all__"

Creating the View


After you create each serializer, the next step is to create a corresponding View function for both the Category

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 593

serializer and the Todo serializer. To do this, open todo/[Link] and add the code shown in the code snippet
that follows. The viewsets class, which provides a default implementation of the CRUD operations, is imported
from rest_framework. The CategoryView and TodoView classes provide a queryset of categories and todo
items, respectively. They also specify the serializer_class defined in the previous section.

# -*- coding: utf-8 -*-


from __future__ import unicode_literals

from [Link] import render,redirect


from rest_framework import viewsets
from .serializers import TodoSerializer, CategorySerializer
from .models import TodoList, Category
import datetime

# Create your views here.

class CategoryView([Link]):
queryset = [Link]()
serializer_class = CategorySerializer

class TodoView([Link]):
queryset = [Link]()
serializer_class = TodoSerializer

Creating the Routers


The next step is to create the routers that provide URL paths for the API. To do this, open the todo/[Link] file
and add the code shown in the code snippet that follows:

from [Link] import path, include


#from todo import views as todo_views
from rest_framework import routers
from [Link] import *

router = [Link]()
[Link](r'categories', CategoryView, basename='Categories')
[Link](r'todos', TodoView, basename='Todos')

urlpatterns = [
path('', index, name="TodoList"),
path(r'api/', include([Link])),
]

Once you complete this step, launch the Django server using the following command:

$ python [Link] runserver

To access the API, launch a browser and navigate to [Link] As shown in Figure 11.21, you
should see two API paths listed, one for categories and another for todo items.
594 11 • Web Applications Development

Figure 11.21 Once the URL paths for the API are created, two API paths are listed—one path for categories and the other for todo.
(rendered in Django, a registered trademark of the Django Software Foundation; attribution: Copyright Rice University, OpenStax,
under CC BY 4.0 license)

Todo items are dependent on categories. To perform CRUD operations on the Category table, click on the
categories API path, as shown in Figure 11.22.

Figure 11.22 The API path can be used to perform CRUD operations on the Category table. (rendered in Django, a registered
trademark of the Django Software Foundation; attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

Once you access the Category List page, enter a category name in the field near the bottom of the page and
click the Post button to save it. You can add additional category names. Once you save each name using the
Post button, the categories will appear in JSON format, as illustrated in Figure 11.23.

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 595

Figure 11.23 The Category List is created in JSON format after saving category names. (rendered in Django, a registered trademark
of the Django Software Foundation; attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

To ensure that categories can be updated or deleted as needed, the primary key, which is “id”, must be
included in the API path (e.g., /api/categories/{id}/). For example, to update or delete the category with id=3,
the API path is /api/categories/3/. As shown in Figure 11.24, once this category is pulled up on the Category
Instance page, the DELETE button is visible at the top to delete the category. If the category needs to be
updated, the PUT button visible near the bottom can be used for updates.

Figure 11.24 The Category Instance page provides DELETE and PUT buttons, which, respectively, can be used to delete or update a
category. (rendered in Django, a registered trademark of the Django Software Foundation; attribution: Copyright Rice University,
OpenStax, under CC BY 4.0 license)

Next, navigate back to the API root. Click on the todos API path to see, as outlined in Figure 11.25, that a Todo
596 11 • Web Applications Development

item has a Category field that appears as a drop-down list of categories. The CRUD operations also can be
performed on the TodoList table. This will be done next through the user interface via templates.

Figure 11.25 After the routers are created, a Todo item has a Category field that appears as a drop-down list of categories, such as
“Work” and “Personal.” (rendered in Django, a registered trademark of the Django Software Foundation; attribution: Copyright Rice
University, OpenStax, under CC BY 4.0 license)

Creating the User Interface


To use and control the Todo application, you must create a user interface (UI). This section will outline the
steps to do this.

Installing Bootstrap
The first step to create a UI is to install Bootstrap, which, as an open-source, responsive web application
framework, can be used in web applications like Django to create UIs. To install Bootstrap in a Django
application, you have several options. In this scenario, an efficient method is to download the Bootstrap CSS
and JS files and add them to the static/ directory, as shown in Figure 11.26. To do this, first create the static/
directory in the Django project directory. In addition, to install jQuery, download the JS file and add it to the
static/ directory. Finally, add a custom CSS file to include individual style in the Django web application.

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 597

Figure 11.26 An efficient method to install Bootstrap in a Django application is to download the Bootstrap CSS and JS files and add
them to the static/ directory. (rendered in Django, a registered trademark of the Django Software Foundation; attribution: Copyright
Rice University, OpenStax, under CC BY 4.0 license)

After adding the CSS and JS files to the static/ directory, the next step is to open the ToDoApp/[Link] file,
navigate to the bottom of the file, and add the path variables shown in the following code snippet.

# Static files (CSS, JavaScript, Images)


# [Link]

STATIC_URL = 'static/'

PROJECT_ROOT = [Link]([Link](__file__))
STATIC_ROOT = [Link](PROJECT_ROOT, 'static')

Creating the View


The next step is to create the View. The View function is needed for template pages, which are created in the
next section. The View function is also needed to interact with the database to both create and delete todo
items.

To create the View, open the todo/[Link] file and add the code shown in the following code snippet. This
code takes an HTTP request object. If the request method is POST, a todo item is either created or deleted,
depending on which button is clicked. Otherwise, the request method is GET and the todo items are displayed
to the user.

def index(request): # index view


todos = [Link]() # query all todos with object manager
categories = [Link]() # get all categories with object manager
if [Link] == "POST": # check if request method is POST
if "taskAdd" in [Link]: # check if request is to add a todo item
title = [Link]["description"] # title
date = str([Link]["date"]) # date
category = [Link]["category_select"] # category
content = title + " -- " + date + " " + category # content
Todo = TodoList(title=title, content=content, due_date=date,
598 11 • Web Applications Development

category=[Link](name=category))
[Link]() # save todo item
return redirect("/") # reload page
if "taskDelete" in [Link]: # check if request is to delete a todo
checkedlist = [Link]["checkedbox"] # checked todos to be deleted
for todo_id in checkedlist:
todo = [Link](id=int(todo_id)) # get todo id
[Link]() # delete todo
return render(request, "[Link]", {"todos": todos, "categories":categories})

Creating the Templates


The final step to build a Django web application is to create templates, which are HTML files that can also
contain embedded Python code. Create a file called [Link] under the /static/css directory and insert the code
shown here into that file. The templates discussed in the following sections require this style sheet.

/* basic reset */
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

/* app */
html {
font-size: 100%;
}

body {
background: #e6f9ff;
font-family: "Open Sans", sans-serif;
}
/* super basic grid structure */
.container {
width: 600px;
margin: 0 auto;
background: #ffffff;
padding: 20px 0;
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
}

.row {
display: block;
padding: 10px;
text-align: center;
width: 100%;
clear: both;
overflow: hidden;

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 599

.half {
width: 50%;
float: left;
}

.content {
background: #fff;
}

/* logo */
h1 {
font-family: "Rokkitt", sans-serif;
color: #666;
text-align: center;
font-weight: 400;
margin: 0;
}

.tagline {
margin-top: -10px;
text-align: center;
padding: 5px 20px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: #777;
}

/* inputs */
.inputContainer {
height: 60px;
border-top: 1px solid #e5e5e5;
position: relative;
overflow: hidden;
}

.[Link] {
border-bottom: 1px solid #e5e5e5;
margin-bottom: 20px;
}

.[Link] {
border-left: 1px solid #efefef;
}

input[type="date"],
input[type="text"],
select {
600 11 • Web Applications Development

height: 100%;
width: 100%;
padding: 0 20px;
position: absolute;
top: 0;
vertical-align: middle;
display: inline-block;
border: none;
border-radius: none;
font-size: 13px;
color: #777;
margin: 0;
font-family: "Open Sans", sans-serif;
font-weight: 600;
letter-spacing: 0.5px;
-webkit-transition: background 0.3s;
transition: background 0.3s;
}

input[type="date"] {
cursor: pointer;
}

input[type="date"]:focus,
input[type="text"]:focus,
select:focus {
outline: none;
background: #ecf0f1;
}

::-webkit-input-placeholder {
color: lightgrey;
font-weight: normal;
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
::-moz-placeholder {
color: lightgrey;
font-weight: normal;
transition: all 0.3s;
}
::-ms-input-placeholder {
color: lightgrey;
font-weight: normal;
transition: all 0.3s;
}
input:-moz-placeholder {
color: lightgrey;
font-weight: normal;
transition: all 0.3s;

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 601

input:focus::-webkit-input-placeholder {
color: #95a5a6;
font-weight: bold;
}

input:focus::-moz-input-placeholder {
color: #95a5a6;
font-weight: bold;
}

.inputContainer label {
padding: 5px 20px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: #777;
display: block;
position: absolute;
}

button {
font-family: "Open Sans", sans-serif;
background: transparent;
border-radius: 2px;
border: none;
outline: none;
height: 50px;
font-size: 14px;
color: #fff;
cursor: pointer;
text-transform: uppercase;
position: relative;
-webkit-transition: all 0.3s;
transition: all 0.3s;
padding-left: 30px;
padding-right: 15px;
}

.icon {
position: absolute;
top: 30%;
left: 10px;
font-size: 20px;
}

.taskAdd {
background: #444;
padding-left: 31px;
602 11 • Web Applications Development

.taskAdd:hover {
background: #303030;
}

.taskDelete {
background: #e74c3c;
padding-left: 30px;
}

.taskDelete:hover {
background: #c0392b;
}

/* task styles */
.taskList {
list-style: none;
padding: 0 20px;
}

.taskItem {
border-top: 1px solid #e5e5e5;
padding: 15px 0;
color: #777;
font-weight: 600;
font-size: 14px;
letter-spacing: 0.5px;
}

.taskList .taskItem:nth-child(even) {
background: #fcfcfc;
}

.taskCheckbox {
margin-right: 1em;
}

.complete-true {
text-decoration: line-through;
color: #bebebe;
}

.taskList .taskDate {
color: #95a5a6;
font-size: 10px;
font-weight: bold;
text-transform: uppercase;
display: block;
margin-left: 41px;

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 603

.fa-calendar {
margin-right: 10px;
font-size: 16px;
}

[class*="category-"] {
display: inline-block;
font-size: 10px;
background: #444;
vertical-align: middle;
color: #fff;
padding: 10px;
width: 75px;
text-align: center;
border-radius: 2px;
float: right;
font-weight: normal;
text-transform: uppercase;
margin-right: 20px;
}

.category- {
background: transparent;
}

.category-Personal {
background: #2980b9;
}

.category-Work {
background: #8e44ad;
}

.category-School {
background: #f39c12;
}

.category-Cleaning {
background: #16a085;
}

.category-Other {
background: #d35400;
}

footer {
text-align: center;
font-size: 11px;
604 11 • Web Applications Development

font-weight: 600;
text-transform: uppercase;
color: #777;
}

footer a {
color: #f39c12;
}
/* custom checkboxes */
.taskCheckbox {
-webkit-appearance: none;
appearance: none;
-webkit-transition: all 0.3s;
transition: all 0.3s;
display: inline-block;
cursor: pointer;
width: 19px;
height: 19px;
vertical-align: middle;
}

.taskCheckbox:focus {
outline: none;
}

.taskCheckbox:before,
.taskCheckbox:checked:before {
font-family: "FontAwesome";
color: #444;
font-size: 20px;
-webkit-transition: all 0.3s;
transition: all 0.3s;
}

.taskCheckbox:before {
content: "\f096";
}

.taskCheckbox:checked:before {
content: "\f14a";
color: #16a085;
}
/* custom select menu */
.taskCategory {
-webkit-appearance: none;
appearance: none;
cursor: pointer;
padding-left: 16.5px; /*specific positioning due to difficult behavior of select
element*/
background: #fff;

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 605

.selectArrow {
position: absolute;
z-index: 10;
top: 35%;
right: 0;
margin-right: 20px;
color: #777;
pointer-events: none;
}

.taskCategory option {
background: #fff;
border: none;
outline: none;
padding: 0 100px;
}

The first template file is [Link], which is the file that includes links to Bootstrap and jQuery. To illustrate
these links, a snippet of the [Link] file is shown in the code. The Bootstrap navigation bar is implemented
in this file.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>TodoApp - Django</title>
{% load static %}
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="/static/css/[Link]" />
<link
rel="stylesheet"
type="text/css"
href="[Link]
[Link]"
/>
<link
rel="stylesheet"
type="text/css"
href="{% static 'css/[Link]' %}"
/>
<!-- jQuery -->
<script
type="text/javascript"
src="{% static 'js/[Link]' %}"></script>
<!-- Popper -->
<script
type="text/javascript"
src="{% static 'js/[Link]' %}"></script>
606 11 • Web Applications Development

<!-- Bootstrap Core JavaScript -->


<script
type="text/javascript"
src="{% static 'js/[Link]' %}"></script>
<script
</head>

<body>
<nav class="navbar navbar-dark bg-dark justify-content-between">
<a class="navbar-brand">ToDo</a>
<form class="form-inline">
<input
class="form-control mr-sm-2"
type="search"
placeholder="Search"
aria-label="Search"
/>
<button class="btn btn-outline-info my-2 my-sm-0" type="submit">
Search
</button>
</form>
</nav>
<div>{% block content %} {% endblock content %}</div>
</body>
</html>

The second template file is [Link], which lists any existing todo items and includes the form to create or
delete a todo item. A snippet of the [Link] file is shown in the following code. The [Link] file also
extends the [Link] template, which allows the Bootstrap navigation bar implemented in [Link] to be
inserted in this page and every page that extends it.

{% extends "./[Link]" %} {% load static %} {% block content %}


<div django-app="TaskManager">
<div class="container mt-5">
<div class="content">
<h1>Todo List</h1>
<!--<p class="tagline">Django Todo App</p>-->
<form action="" method="post">
{% csrf_token %}
<!-- csrf token for basic security -->
<div class="inputContainer">
<input type="text" id="description" class="taskName"
placeholder="What do you need to do?" name="description"
required />
<label for="description">Description</label>
</div>
<div class="inputContainer half last">
<i class="fa fa-caret-down selectArrow"></emphasis>
<select id="category" class="taskCategory" name="category_select">
<option class="disabled" value="">Choose a category</option>

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 607

{% for category in categories %}


<option class="" value="{{ [Link] }}" name="{{
[Link] }}" >
{{ [Link] }}
</option>
{% endfor %}
</select>
<label for="category">Category</label>
</div>
<div class="inputContainer half last right">
<input type="date" id="dueDate" class="taskDate" name="date" />
<label for="dueDate">Due Date</label>
</div>
<div class="row">
<button class="taskAdd" name="taskAdd" type="submit">
<i class="fa fa-plus icon"></emphasis>Add task
</button>
<button class="taskDelete" name="taskDelete"
formnovalidate="" type="submit"
>
<i class="fa fa-trash-o icon"></emphasis>Delete Tasks
</button>
</div>
<ul class="taskList">
{% for todo in todos %}
<!-- django template lang - for loop -->
<li class="taskItem">
<input type="checkbox" class="taskCheckbox"
name="checkedbox" id="{{ [Link] }}" value="{{ [Link] }}"
/>
<label for="{{ [Link] }}" ><span class="complete-">{{ [Link]
}}</span></label>
<span class="category-{{ [Link] }}" >{{ [Link]
}}</span>
>{{ [Link] }}</span
<strong class="taskDate" ><i class="fa fa-calendar"></emphasis>Created:
{{[Link]}} - Due:
>{{ [Link] }}</span
{{todo.due_date}}</strong>
>{{ [Link] }}</span
</li>
{% endfor %}
</ul>
<!-- taskList -->
</form>
</div>
<!-- content -->
</div>
<!-- container -->
</div>
608 11 • Web Applications Development

{% endblock %}

The first step to access the Todo Django web application is to restart the Django server using the following
command:

$ python [Link] runserver

Next, launch a browser and navigate to [Link] The page highlighted in Figure 11.27 should
appear.

Figure 11.27 Once the Django server is restarted, this page should appear at [Link] (rendered in Django, a registered
trademark of the Django Software Foundation; attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

To create a todo list, fill out the form and click the Add Task button as shown in Figure 11.28.

Access for free at [Link]


11.2 • Sample Responsive WAD with Bootstrap and Django 609

Figure 11.28 This figure shows how the Todo List should appear after using the Add Task button to create a todo list. (rendered in
Django, a registered trademark of the Django Software Foundation; attribution: Copyright Rice University, OpenStax, under CC BY 4.0
license)

In addition, the todo item should also be viewable in the API that was created. This should appear as outlined
in Figure 11.29.
610 11 • Web Applications Development

Figure 11.29 Once the todo item is created, it should be viewable in the API. (rendered in Django, a registered trademark of the
Django Software Foundation; attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

11.3 Sample Responsive WAD with Bootstrap/React and Node


Learning Objectives
By the end of this section, you will be able to:
• Create a Todo web application with Bootstrap, React, and Node
• Create a Node back end
• Build the controller
• Set up the REST API
• Create the React front end
• Connect the React front end to the Node back end

In the previous section, you created a simple Todo application using Bootstrap and Django. In this section, you
will continue to use Bootstrap to create another simple Todo application. But instead of working with Django,
you will use React and Node. React, or [Link], is a JavaScript library popular to build user interfaces. Node, or
[Link], is a JavaScript runtime environment that provides users with the tools to develop web applications, as
well as servers, scripts, and command-line tools.

Access for free at [Link]


11.3 • Sample Responsive WAD with Bootstrap/React and Node 611

Creating a Todo Web Application with Bootstrap and React and Node
When creating a Todo web application using React and Node, React serves as the front end, handling the user
interface, as well as getting and setting data via HTTP requests using Axios. Node serves as the back end,
using a REST API built with ExpressJS and the MongooseJS Object Data Modeling (ODM) to interact with a
MongoDB database.

Prerequisites
To build the Todo application using Bootstrap, React, and Node, you will need the following software
components: React v17.0.2, Bootstrap v4.5.0, Node v14.17.5, ExpressJS v4.17.2, MongooseJS v6.1.9, and Axios
v0.21.0. To begin, download and install Node.

Creating the Node Back End


Several steps are needed to build the Node application back end required for the Todo application. This section
will explain each of these steps.

LINK TO LEARNING

Node ([Link] is a JavaScript runtime environment that provides users with the
tools to develop web applications, as well as servers, scripts, and command-line tools. Node, which is free,
is open-source and cross-platform. It was designed to develop network applications that are scalable,
managing many connections simultaneously. Unlike the typical inefficient concurrency model, with Node, a
callback is fired with each connection, and Node sleeps unless work needs to be done.

Creating the Node App


Before you can create the Todo application back end, you should create a Node app. To accomplish this, create
the directory nodebackend/ and navigate into it. Next, run the following command to initialize the Node
application:

$ npm init

After running this command, follow the prompt, which is highlighted in Figure 11.30.

Figure 11.30 This prompt appears when the Node application is initialized. (attribution: Copyright Rice University, OpenStax, under
CC BY 4.0 license)
612 11 • Web Applications Development

After the Node application initialization is completed, a [Link] file is generated, as shown in the
following code.

{
"name": "nodebackend",
"version": "1.0.0",
"description": "Todo Web application with Bootstrap, ReactJS and NodeJS",
"main": "[Link]",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"bootstrap",
"reactjs",
"nodejs",
"express",
"mongodb",
"rest",
"api"
],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.1",
"cors": "^2.8.5",
"express": "^4.17.2",
"mongoose": "^6.1.9"
}
}

Setting Up the Express Web Server


Once the Node application is initialized, the next step is to set up the Express web server. To do this, use the
following command to install Express, Mongoose (Mongoose is a library for MongoDB that is used to interact
with MongoDB by facilitating the modeling of data as objects), and other dependent packages in the
nodebackend/ directory:

$ npm install express mongoose body-parser cors –save

Next, create the Express web server by going to the nodebackend/ directory, create the [Link] file, and add
the following code.

const express = require("express");


const bodyParser = require("body-parser");
const cors = require("cors");

const app = express();

var corsOptions = {
origin: "[Link]
};

Access for free at [Link]


11.3 • Sample Responsive WAD with Bootstrap/React and Node 613

[Link](cors(corsOptions));

// parse requests of content-type - application/json


[Link]([Link]());

// parse requests of content-type - application/x-www-form-urlencoded


[Link]([Link]({ extended: true }));

// routes
[Link]("/", (req, res) => {
[Link]({ message: "Welcome to the Todo Web App." });
});

require("./routes/[Link]")(app);

// set port, listen for requests


const PORT = [Link] || 8080;
[Link](PORT, () => {
[Link](`Server is running on port ${PORT}.`);
});

Once you use the code to import Express, you can build the REST APIs. The body-parser package is used to
create and parse the request object. The cors package is used to serve as middleware for Express that enables
CORS. The Express web server will run on port 8080 as the default port. Use the following command to start
the server:

$ node [Link]

In a browser, navigate to [Link] The following page shown in Figure 11.31 renders.

Figure 11.31 Once the Express web server is started, this page should appear at [Link] (rendered in Node;
attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

Configuring the MongoDB Database and Mongoose


After the Express web server is created, the next step is to configure the MongoDB database and Mongoose.
To do this, in the nodebackend/ directory, create the config/ directory. Then, in the config/ directory, create the
file [Link] and add the following code. This specifies the database connection URL to the MongoDB
database.

[Link] = {
url: "mongodb://localhost:27017/todo_db"
};
614 11 • Web Applications Development

Once the MongoDB connection URL is configured, the next step is to add code to connect to the database
using Mongoose. To do this, in the nodebackend/ directory, create the models/ directory. In the models/
directory, create the [Link] file and add the following.

const dbConfig = require("../config/[Link]");

const mongoose = require("mongoose");


[Link] = [Link];

const db = {};
[Link] = mongoose;
[Link] = [Link];
[Link] = require("./[Link]")(mongoose);

[Link] = db;

Next, the nodebackend/[Link] file needs to be updated to enable the Express web server to establish a
connection with the MongoDB. The code for this is shown in the following snippet.

const db = require("./models");
[Link]([Link], {
useNewUrlParser: true
}).then(() => {
[Link]("Connected to the database successfully!")
}).catch(err => {
[Link]("Cannot connect to the database: " , err);
[Link]();
});

Once the database connection code is completed, the next step is to create the Mongoose model. To do this, in
the nodebackend/models/ directory, create the file [Link] and add the following code. This code
defines a Mongoose schema for the todos model, which results in the creation of a todos collection in the
MongoDB database.

[Link] = mongoose => {


var schema = [Link]({
title: {
type: String,
required: true,
},
content: {
type: String,
required: false,
},
created: {
type: String,
default: [Link](),
required: true,
},
due_date: {
type: String,

Access for free at [Link]


11.3 • Sample Responsive WAD with Bootstrap/React and Node 615

required: true,
},
category: {
type: String,
required: true,
},
});

[Link]("toJSON", function() {
const { __v, _id, ...object } = [Link]();
[Link] = _id;
return object;
});
const Todos = [Link]("todos", schema);
return Todos;
};

Building the Controller


The next step is to build the controller. The controller contains code that calls the Mongoose CRUD functions to
interact with the MongoDB database. To build the controller, in the nodebackend/ directory, create the
controllers/ directory. Then, in the controllers/ directory, create the file [Link] and add the code as
shown. The code implements the CRUD functions create, findAll, findOne, update, delete, and deleteAll.

const db = require("../models");
const Todos = [Link];

// Create and Save a new Todo item


[Link] = (req, res) => {
// Validate requred data
if (![Link]) {
[Link](400).send({ message: "Title can not be empty!" });
return;
}
if (![Link]) {
[Link](400).send({ message: "Category can not be empty!" });
return;
}
if (![Link].due_date) {
[Link](400).send({ message: "Due date can not be empty!" });
return;
}

// Create a todo item


const todo = new Todos({
title: [Link],
content: [Link],
category: [Link],
due_date: [Link].due_date
});
616 11 • Web Applications Development

// Save the todo item in the database


todo
.save(todo)
.then(data => {
[Link](data);
})
.catch(err => {
[Link](500).send({
message:
[Link] || "An error occurred while creating the todo item."
});
});
};

// Retrieve all todo items


[Link] = (req, res) => {
const title = [Link];
var condition = title ? { title: { $regex: new RegExp(title), $options: "i" } } :
{};

[Link](condition)
.then(data => {
[Link](data);
})
.catch(err => {
[Link](500).send({
message:
[Link] || "An error occurred while retrieving todo items."
});
});
};

// Retrieve a todo item by id


[Link] = (req, res) => {
const id = [Link];

[Link](id)
.then(data => {
if (!data)
[Link](404).send({ message: "Error finding todo item with id " + id });
else [Link](data);
})
.catch(err => {
res
.status(500)
.send({ message: "Error retrieving todo item with id=" + id });
});
};

// Update a todo item by id

Access for free at [Link]


11.3 • Sample Responsive WAD with Bootstrap/React and Node 617

[Link] = (req, res) => {


if (![Link]) {
return [Link](400).send({
message: "Specify a todo item to update. Todo item cannot be empty!"
});
}

const id = [Link];

[Link](id, [Link], { useFindAndModify: false })


.then(data => {
if (!data) {
[Link](404).send({
message: `Cannot update todo item with id=${id}. Todo item was not found!`
});
} else [Link]({ message: "The todo item was updated successfully." });
})
.catch(err => {
[Link](500).send({
message: "Error updating todo item with id=" + id
});
});
};

// Delete a todo item by id


[Link] = (req, res) => {
const id = [Link];

[Link](id, { useFindAndModify: false })


.then(data => {
if (!data) {
[Link](404).send({
message: `Cannot delete todo item with id=${id}. Todo item was not found!`
});
} else {
[Link]({
message: "The todo item was deleted successfully!"
});
}
})
.catch(err => {
[Link](500).send({
message: "Error deleting todo item with id=" + id
});
});
};

// Delete all todo items from the database


[Link] = (req, res) => {
[Link]({})
618 11 • Web Applications Development

.then(data => {
[Link]({
message: `${[Link]} All todo items were deleted successfully!`
});
})
.catch(err => {
[Link](500).send({
message:
[Link] || "An error occurred while deleting all todo items."
});
});
};

Set Up the REST API


Once the controller is built, the next step is to set up the REST API. A client will send HTTP requests (e.g., GET,
POST, PUT, and DELETE) to the REST API endpoints that determine how the server will manage these requests
and provide a response. To do this, routes for the REST API are first defined. In the nodebackend/ directory,
create the routes/ directory. In the routes/ directory, create the file [Link] and add the following code.
In this code, the routes require access to the CRUD functions declared in the controller.

module .exports = app => {


const todos = require("../controllers/[Link]");
var router = require("express").Router();

// Create a new todo item


[Link]("/", [Link]);

// Retrieve all todo items


[Link]("/", [Link]);

// Retrieve a todo item by id


[Link]("/:id", [Link]);

// Update a todo item by id


[Link]("/:id", [Link]);

// Delete a todo item by id


[Link]("/:id", [Link]);

// Delete all todo items


[Link]("/", [Link]);

[Link]("/api/todos", router);

};

The next step is to update nodebackend/[Link] to import the routes shown in the following code.

// routes
[Link]("/", (req, res) => {

Access for free at [Link]


11.3 • Sample Responsive WAD with Bootstrap/React and Node 619

[Link]({ message: "Welcome to the Todo Web App." });


});

require("./routes/[Link]")(app);

// set port, listen for requests


const PORT = [Link] || 8080;
[Link](PORT, () => {
[Link](`Server is running on port ${PORT}.`);
});

The next step is to run the Express web server to test the CRUD functions and interact with the MongoDB
database. To do this, run the following command:

$ node [Link]

LINK TO LEARNING

As an API platform Postman ([Link] can be a useful programming interface to


build and use APIs. Postman is simplified, making it easier to build APIs quickly. With Postman, developers
can also test and modify APIs to ensure they meet specifications.

To test the REST API, use Postman, which is an API platform testing tool that can be used as a client. To
accomplish this, follow these steps:

• Install and launch Postman.


• Select POST as the request method.
• Enter the URL [Link] to test creating a todo item.
• In the data input frame, select “Body.”
• Select “raw” and “JSON” for the data format.
• Enter a JSON object representing a todo item to be created as shown.
• Click Send.

After you follow these steps, the bottom frame should receive a response with status “200 OK” indicating the
request was handled successfully. The body of the created todo item will also display along with a generated id
field. You can use this method to test all the CRUD functions.

Creating the React Front End


Once you complete these steps and have the back end of the Todo web application up and running, the next
step is to implement the front end using React. This section will outline the steps to accomplish this.

LINK TO LEARNING

React ([Link] is a JavaScript library popular to build user interfaces. It relies on


individual pieces known as components, which are JavaScript functions. React components are created
using code and markup, and once created, React components can be combined to develop applications,
screens, and web pages. React also has the capability to be added to HTML pages, rather than building an
entire page using React.
620 11 • Web Applications Development

Creating the React App


To create the React app, the first step is to run the following command. This should be done in a directory that
is outside and separate from the nodebackend/ directory.

$ npx create-react-app reactfrontend

Once you run the command, it will generate the React application files in the reactfrontend/ directory, which is
shown in Figure 11.32.

Figure 11.32 This shows the React application files in the reactfrontend/ directory. (rendered in React by Meta Open Source;
attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

The next step is to navigate into the reactfrontend/ directory and launch the React application to confirm the
React front-end application was created successfully. At this point, this application is not connecting to the
Node back end, so it launches a default React page. Run the command, which will automatically launch a
browser page to [Link]

$ npm start

You will see the following, as illustrated in Figure 11.33.

Figure 11.33 When the React front-end application is created successfully, this page launches at [Link] (credit: React
by Meta Open Source)

Access for free at [Link]


11.3 • Sample Responsive WAD with Bootstrap/React and Node 621

Installing Bootstrap and Other Dependencies


The next step is to install the packages for bootstrap and reactstrap, which are necessary to use Bootstrap in a
React app. To do this, in the reactfrontend/ directory, run the following commands:

$ npm install bootstrap@4.6.0 reactstrap@8.9.0 --legacy-peer-deps


$ npm install react-bootstrap

4
Next, import the Bootstrap CSS file into the React application. To do this, open reactfrontend/src/[Link] and
add the following Bootstrap import.

import React from 'react';


import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/[Link]';
import './[Link]';
import App from './App';
import reportWebVitals from './reportWebVitals';

[Link](
<[Link]> <App /> </[Link]>,
[Link]('root')
);

// If you want to start measuring performance in your app, pass a function


// to log results (for example: reportWebVitals([Link]))
// or send to an analytics endpoint. Learn more: [Link]
reportWebVitals();

Create the React Components


The next step is to create the React components. The React user interface is rendered from the reactfrontend/
src/[Link] component. The reactfrontend/src/[Link] file is generated when the React application is created.
This is the main component of the React application, and all other components are added to the
reactfrontend/src/[Link] component. A few imports are added to the reactfrontend/src/[Link] file, as shown in
the following code. This includes an import for [Link]. Customized CSS rules are added to reactfrontend/src/
[Link].

//import logo from './[Link]';


import './[Link]';
import React, { Component } from "react";
import Modal from "./components/Modal";
import Nav from "./components/NavComponent";
import axios from "axios";
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';

To compare with the Django web application in 11.2 Sample Responsive WAD with Bootstrap and Django,
customized CSS rules were added to the [Link] file in the static/ directory, as described in Creating the
Templates.

Next, look at the following code, which shows App is a class component that extends React’s Component class.
All state data is added to the [Link] variable in the constructor.

4 Boostrap is a web content framework documented at [Link].


622 11 • Web Applications Development

class App extends Component {


constructor(props) {
super(props);
[Link] = {
todoChecked: false,
todoList: [],
categories: [],
description: "",
modal: false,
activeItem: {
title: "",
description: "",
completed: false,
},
};
}

The next code snippet shows that every class component must include a render() function. This function
returns the components that construct the user interface for the Todo web application.

render () {
return(
<main> <Nav /> <div className="container mt-5 pl-3">
<h1>Todo List</h1> <Form> <div
className="inputContainer"> <FormGroup> <Label
htmlFor="description">Description</Label> <Input type="text"
id="description" name="description" placeholder="Description"
value={[Link]} />
</FormGroup> </div> <div
className="inputContainer half last"> <FormGroup>
<Label htmlFor="category">Category</Label> <Input
id="category" className="taskCategory" type="select" name="category_select"
value={[Link]} >
<option className="disabled" value="">Choose a category</option>
<option>Work</option>
<option>Personal</option> </Input>
</FormGroup> </div> <div
className="inputContainer half last right"> <FormGroup>
<Label htmlFor="description">Due Date</Label>
<Input type="text" id="description" name="description"
placeholder="Due Date (mm/dd/yyyy)"
value={[Link]} />
</FormGroup> </div> <div className="row">
<Button className="taskAdd"
name="taskAdd" type="submit" >
Edit </Button> <Button
className="taskDelete ml-1" name="taskDelete"
type="submit"
>
Delete </Button> </div>

Access for free at [Link]


11.3 • Sample Responsive WAD with Bootstrap/React and Node 623

</Form> <ul className="taskList">{[Link]()}</ul>


</div> </main>
)
}

Connecting the React Front End to the Node Back End


The final step to create the Todo web application is to configure the React application so it can make requests
to the API endpoints of the Node application. The React application uses Axios to fetch data by making
requests to a given endpoint. To install Axios, run the following command in the reactfrontend/ directory:

$ npm install axios@0.21.1

Next, add a proxy to the Node application. The proxy will help tunnel API requests from the React application
to [Link] where the Node application will receive and handle the requests. To do this, open the
reactfrontend/[Link] file and add the following proxy.

{
"name": "reactfrontend",
"version": "0.1.0",
"private": true,
"proxy": "[Link]
"dependencies": {

The next step is to create a service on the front end to send HTTP requests to the back end. This process uses
Axios and is similar to how routes were created on the back-end side. The service will export CRUD functions
and a finder method to interact with the MongoDB database. To do this, in the reactfrontend/ directory, create
the services/ directory. Then, in the services/ directory, create the tile [Link] and add the following
code.

import axios from "axios";

const getAll = () => {


return [Link]("/api/todos/");
};

const get = id => {


return [Link](`/api/todos/${id}`);
};

const create = data => {


return [Link]("/api/todos", data);
};

const update = (id, data) => {


return [Link](`/api/todos/${id}`, data);
};

const remove = id => {


return [Link](`/api/todos/${id}`);
624 11 • Web Applications Development

};

const removeAll = () => {


return [Link](`/api/todos`);
};

export default {
getAll,
get,
create,
update,
remove,
removeAll
};

Finally, to complete this step, update reactfrontend/[Link] to the following to call the services.

handleSubmit = (item) => {


var data = {
id: [Link],
title: [Link],
content: [Link],
due_date: item.due_date,
category: [Link]
};

[Link](data)
.then((res) => [Link]())
.catch((err) => [Link](err));
};
handleUpdate = (item) => {
var data = {
id: [Link],
title: [Link],
content: [Link],
due_date: item.due_date,
category: [Link]
};
[Link]([Link], data)
.then((res) => [Link]())
.catch((err) => [Link](err));
};
handleDelete = (item) => {
[Link]([Link])
.then((res) => [Link]())
.catch((err) => [Link](err));
};
refreshList = () => {
[Link]()
.then((res) => [Link]({ todoList: [Link] }))

Access for free at [Link]


11.4 • Sample Responsive WAD with Bootstrap/React and Django 625

.catch((err) => [Link](err));


}

Once this is completed, run both the Express web server and the React app using the following commands:

$ node [Link]
$ npm start

When this is done, use the form shown in Figure 11.34 to create a new todo item.

Figure 11.34 Once the Todo web application is created using Bootstrap with React and Node, this form can be used to create todo
items. (rendered using Bootstrap, under MIT license copyrighted 2018 Twitter, with React by Meta Open Source and Node;
attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

11.4 Sample Responsive WAD with Bootstrap/React and Django


Learning Objectives
By the end of this section, you will be able to:
• Update the Todo web application with Bootstrap, React, and Django
• Extend the Django back end to support the React front end
• Connect the React front end to the Django back end

Previously, you learned how to build a Todo web application using Bootstrap and Django and then using
Bootstrap with React and Node. This section will review the steps required to update the Todo web application
using Bootstrap with React and Django.

Updating the Todo Web Application with Bootstrap, React, and Django
In this section, the Todo web application implemented will build on the Django application covered in 11.2
Sample Responsive WAD with Bootstrap and Django, as well as the React application explored in 11.3 Sample
Responsive WAD with Bootstrap/React and Node. For this version of the Todo web application, React serves as
the front end handling the user interface to get and set data via HTTP requests. Django serves as the back end.
626 11 • Web Applications Development

Prerequisites
To build this version of the Todo application, you need Python v3.9.4, PIP v21.3.1, Django v4.0.1, Django REST
Framework v3.13.1, Bootstrap v4.5.0, Django-cors-headers v3.11.0, React v17.0.2, and Axios v0.21.0. To begin,
complete the following steps:

• Activate the venv used in section 11A.2:


$ cd py394venv
Windows: $ source ./Scripts/activate
macOS: $ source ./bin/activate
• Install in the local programming environment Django Cors Headers
$ pip install django-cors-headers==3.11.0 ]

LINK TO LEARNING

When using Django, Cross-Origin Resource Sharing (CORS) headers ([Link]


76CORSheaders) can be a valuable tool to allow a Django application to accept in-browser requests that
come from other origins. With CORS headers, other domains can access your resources, but only if
permitted. When used appropriately, this makes CORS an important tool to boost a website’s security.

Extending the Django Back End to Support the React Front End
To create a Todo web application using React as a front end to the Django back end, the Django project
requires a couple of configurations. Open TodoApp/[Link] and add ‘corsheaders’ to INSTALLED_APPS as in
the following code.

INSTALLED _APPS = [
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'corsheaders',
'rest_framework',
'todo',
]

By configuring the Django project with CORS, the Django application will be allowed to accept in-browser
requests that come from other origins. To add CORS, add the CORS middleware to MIDDLEWARE, as shown in
the following code.

MIDDLEWARE = [
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',

Access for free at [Link]


11.4 • Sample Responsive WAD with Bootstrap/React and Django 627

After completing this step, scroll to the bottom of the [Link] file and add the following variable.

# add CORS whitelist for localhost:3000 since the React frontend will be served on
port 3000
CORS_ORIGIN_WHITELIST = [
'[Link]
]

LINK TO LEARNING

Axios is an HTTP client for Node that manages asynchronous HTTP requests. Axios is free and open-source,
with built-in security measures. Axios uses clean, efficient syntax to manage promises, and works well with
Node, as well as browser environments. Visit this page on Axios ([Link] to learn
more.

Connecting the React Front End to the Django Back End


Next, the React application must be configured so it can make requests to the API endpoints of the Django
application. The React application uses Axios to fetch data by making requests to a given endpoint. To install
Axios, run the following command in the reactfrontend/ directory:

$ npm install axios@0.21.1

Next, add a proxy to the Django application. The proxy will help tunnel API requests from the React application
to [Link] where the Django application will receive and handle the requests. To add the proxy,
open the reactfrontend/[Link] file and add the following code.

{
"name": "reactfrontend",
"version": "0.1.0",
"private": true,
"proxy": "[Link]
"dependencies": {

After completing this step, open the reactfrontend/src/[Link] file and import Axios, as shown in the following
code.

import './[Link]';
import React, { Component } from "react";
import Modal from "./components/Modal";
import Nav from "./components/NavComponent";
import axios from "axios";
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';

To update the reactfrontend/src/[Link] file, add the following code. The handleSubmit() function will use
Axios to make requests to the Django API endpoints to create and delete todo items.

handleSubmit = (item) => {


[Link]();
628 11 • Web Applications Development

if ([Link]) {
axios
.put(`/api/todos/${[Link]}/`, item)
.then((res) => [Link]());
return;
}
axios
.post("/api/todos/", item)
.then((res) => [Link]());
};

handleDelete = (item) => {


axios
.delete(`/api/todos/${[Link]}/`)
.then((res) => [Link]());
};

When these steps are complete, start up the Django server and then start up the React application, using the
following commands, respectively.

$ python [Link] runserver


$ npm start

To access the Django REST API, navigate to [Link] This is similar to the steps completed in
11.2 Sample Responsive WAD with Bootstrap and Django. Click on the categories API path to enter two
categories, as seen in Figure 11.35.

Figure 11.35 After navigating to [Link] and following the instructions provided, this page will appear to allow
access to the Django REST API. (rendered in React by Meta Open Source; attribution: Copyright Rice University, OpenStax, under CC
BY 4.0 license)

Access for free at [Link]


11.4 • Sample Responsive WAD with Bootstrap/React and Django 629

When the React application starts up, a browser page will automatically launch for navigating to
[Link] and the user interface should render. Figure 11.36 shows the page on which to create a
todo item.

Figure 11.36 After the React application starts up, this user interface will appear. (rendered in React by Meta Open Source;
attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

At this point, revisit the Django REST API. Figure 11.37 shows that the todo item should be accessible via the
todos API path.
630 11 • Web Applications Development

Figure 11.37 Once the Todo web application is updated using Bootstrap with Django and React, this page should appear to allow
users to create a Todo List. (rendered using Bootstrap under MIT license copyrighted 2018 Twitter; with Django, a registered
trademark of the Django Software Foundation; and React by Meta Open Source; attribution: Copyright Rice University, OpenStax,
under CC BY 4.0 license)

11.5 Sample Native WAD with React Native and Node or Django
Learning Objectives
By the end of this section, you will be able to:
• Create a Todo native mobile application with React Native or Node
• Create a React Native app and its components
• Connect the front-end Native app with the back-end Node app

In the previous sections, you worked with Bootstrap, Django, React, and Node to build versions of a Todo web
application. In this section, you will learn how to use React Native and Node to develop a Todo application for
mobile devices. You are already familiar with Node. Like React, React Native is an open-source JavaScript
framework used to build native applications for mobile devices.

LINK TO LEARNING

React Native ([Link] uses the React JavaScript library to enable native
development and build user interfaces for mobile devices. React Native has the flexibility to work with
Xcode, which is the IDE for various platforms. Released by Facebook (now Meta) in 2015, React Native has
become increasingly popular among developers.

Access for free at [Link]


11.5 • Sample Native WAD with React Native and Node or Django 631

Creating a Todo Web Application with React Native and Node


This application uses React Native and Node to implement a simple Todo mobile application. This application
builds on top of the React and Node application discussed in 11.3 Sample Responsive WAD with Bootstrap/
React and Node. For this version of the application, React Native serves as the front end handling the user
interface and getting and setting data via HTTP requests. Node serves as the back end that makes use of the
API built using the Django REST Framework in 11.2 Sample Responsive WAD with Bootstrap and Django.

Prerequisites
To build the Todo mobile application using React Native and Node, you need React Native v0.67, Node
v14.17.5, ExpressJS v4.17.2, MongooseJS v6.1.9, and Axios v0.21.0. This Todo application will run using the
Android emulator and will use Android Studio v2021.1.1.

LINK TO LEARNING

Xcode ([Link] is the IDE for the Apple platform. For Apple, React Native provides
developers with the tools needed for cross-platform development that creates user-friendly apps on mobile
devices.

• To begin, download and install an emulator for your intended platform (iOS or Android).
• If you plan to run the native app on an iOS device or emulator, download and install Xcode, which is
Apple’s IDE that enables application development for Apple’s platforms.
• If you plan to run the native app on an Android device or emulator, download and install Android Studio,
which enables application development for Android mobile operating systems.
• Figure 11.38 shows how to set up the Android emulator. Launch Android Studio. From the top navigation,
select Tools > Device Manager. Click on Create device. In the Select Hardware pop-up, select Pixel 5 and
click Next. On the next page, select Pie Download. Click on the Download link to obtain an image as
shown. Click Next followed by Finish.
632 11 • Web Applications Development

Figure 11.38 This shows how to set up the Android emulator. (Android Studio is a trademark of Google LLC.)

Once the image has been created, it will appear in the Device Manager. Next, click on the Start button to
launch the emulator. When the emulator is launched, it will turn on, as shown in Figure 11.39.

Access for free at [Link]


11.5 • Sample Native WAD with React Native and Node or Django 633

Figure 11.39 This is how the emulator will appear after it is launched. (Android Studio is a trademark of Google LLC.)

LINK TO LEARNING

Xcode also integrates well with Android Studio ([Link] for developing
Android apps. Android Studio is the IDE for Android devices.

Creating the React Native App


After launching the emulator, create the React Native app by running the following command in a directory
outside and separate from the nodebackend/ directory. Figure 11.40 shows the React Native application files in
the reactnativefrontend/ directory.

$ npx react-native init reactnativefrontend


634 11 • Web Applications Development

Figure 11.40 When the React Native app is created, it will generate the React Native application files in the reactnativefrontend/
directory. (rendered in React Native, under MIT license; attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

Next, navigate into the reactnativefrontend/ directory and launch the React Native application to confirm that
the React Native front-end application has been created successfully. At this point, the application is not
connected to the Node back end and will launch the Metro bundler, which bundles the JavaScript code that is
deployed on the mobile device or emulator when the React Native front-end application is successfully
completed. When this is done, run the command. Figure 11.41 shows the page in the terminal.

$ npx react-native start

Access for free at [Link]


11.5 • Sample Native WAD with React Native and Node or Django 635

Figure 11.41 This page will appear when the react-native start command is run. (credit: React Native, under MIT license)

The next step is to open another terminal, navigate to the reactnativefrontend/ directory, and run the
following command. This will build the front-end code and deploy it on the emulator, which may take a few
minutes.

$ npx react-native run-android

When the application is successfully built, Figure 11.42 shows what should appear in the second terminal.
636 11 • Web Applications Development

Figure 11.42 This code should appear in the second terminal when the React Native application is successfully built. (attribution:
Copyright Rice University, OpenStax, under CC BY 4.0 license)

Figure 11.43 shows how the native application should appear in the emulator.

Access for free at [Link]


11.5 • Sample Native WAD with React Native and Node or Django 637

Figure 11.43 Once the React Native application is successfully built, this is how the native application should appear in the emulator.
(Android Studio is a trademark of Google LLC.)

Creating the React Native App Components


The packages used by the React Native app for navigation and other features are different from the packages
used by React. To install the required packages, in the reactnativefrontend/ directory, run the following list of
commands:

$ npm install @react-navigation/native@6.0.7


$ npm install @react-navigation/native-stack@6.3.0
$ npm install axios@0.25.0
$ npm install moment@2.29.1
$ npm install react-native-modal@13.0.0
$ npm install react-native-safe-area-context@3.3.2
$ npm install react-native-screens@3.10.2
$ npm install react-native-snackbar@2.4.0
$ npm install react-native-vector-icons@9.0.0

The first step is to create the Todo component. In the reactnativefrontend/ directory, create the directory src/
Screens/. In the src/Screens/ directory, create the file [Link]. The following code shows the imports
required to create the screen components.
638 11 • Web Applications Development

import React, {useState, useEffect} from 'react';


import {
View,
Text,
StyleSheet,
TextInput,
FlatList,
TouchableOpacity,
Dimensions,
StatusBar,
Alert,
} from 'react-native';
import axios from 'axios';
import {COLORS} from '../utils/colors';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
import Modal from 'react-native-modal';
import Snackbar from 'react-native-snackbar';
import {duration} from 'moment';

Once this is done, the following code includes the return() function that renders the screen components.

return (
<View style={[Link]}> <StatusBar backgroundColor={[Link]} />
<Text style={[Link]}>Welcome to Todo List App!</Text> <Text
style={[Link]}>Your Tasks</Text> {[Link] == 0 ? ( <View
style={[Link]}> <MaterialCommunityIcon name="note-multiple"
size={90} color={[Link]} /> <Text
style={[Link]}>No Tasks Added</Text> </View> ) : ( <>
<View style={[Link]}> <FlatList
data={todos} renderItem={({item}) => ( <View
style={[Link]}> <Text style={[Link] ?
[Link] : [Link]}> {[Link]}
</Text> <TouchableOpacity
style={[Link]} =>
deleteTodo(item._id)}> <Text style={{color: [Link]}}>X</Text>
</TouchableOpacity> </View> )} />
</View> <TouchableOpacity style={[Link]}
=> { setModalActive(true); }}>
<MaterialIcon name="add" size={32} color={[Link]} />
</TouchableOpacity> </>
)}

<Modal
isVisible={modalActive}
animationIn={'slideInUp'}
animationOut={'slideInDown'}>
<View style={[Link]}> <TouchableOpacity
style={[Link]} =>
setModalActive(false)}> <Text style={[Link]}>X</Text>

Access for free at [Link]


11.5 • Sample Native WAD with React Native and Node or Django 639

</TouchableOpacity> <Text style={[Link]}>Add


Task</Text> <TextInput style={[Link]}
placeholder="Enter task here.." =>
setNewTodo(text)} value={newTodo} /> <TouchableOpacity
style={[Link]} => addTodo()}> <Text
style={[Link]}>Create Task</Text> </TouchableOpacity>
</View>
</Modal>
</View>
);

The following code creates the modal pop-up screen that is used to create a Todo list.

<Modal
isVisible={modalActive}
animationIn={'slideInUp'}
animationOut={'slideInDown'}>
<View style={[Link]}> <TouchableOpacity
style={[Link]} => setModalActive(false)}>
<Text style={[Link]}>X</Text> </TouchableOpacity>
<Text style={[Link]}>Add Task</Text> <TextInput
style={[Link]} placeholder="Enter task here.."
=> setNewTodo(text)} value={newTodo} />
<TouchableOpacity style={[Link]} => addTodo()}> <Text
style={[Link]}>Create Task</Text> </TouchableOpacity> </View>
</Modal>

Next, update the reactnativefrontend/[Link] file, as shown in the following code, to render the screen
components declared in the [Link] file.

import React from 'react';


import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import TodoList from './src/Screens/TodoList';

const Stack = createNativeStackNavigator();

const App = () => {


return (
<NavigationContainer> <[Link]> <[Link]
name="TodoList" component={TodoList}
options={{headerShown: false}} /> </[Link]>
</NavigationContainer>
);
};
export default App;

When this is done, relaunch the Metro bundler and deploy the native application by running the following
commands:

$ npx react-native start


640 11 • Web Applications Development

$ npx react-native run-android

Next, create a Todo item (Figure 11.44).

Figure 11.44 After relaunching the Metro bundler and deploying the native application, this screen allows users to create a Todo
item. (Android studio is a trademark of Google LLC.)

After the Todo item is created, it should appear on the main screen as seen in Figure 11.45.

Access for free at [Link]


11.5 • Sample Native WAD with React Native and Node or Django 641

Figure 11.45 Here is how the Todo item should appear on the main screen. (Android studio is a trademark of Google LLC.)

Connecting the Front-End Native App with the Back-End Node App
The next step is to connect the front-end React Native app with the back-end Node app. To do this, open
reactnativefrontend/src/Screens/[Link]. Add the API_BASE variable and configure the IP address to the
local computer, running the Express web server, as shown in the following code.

import axios from 'axios';


import {COLORS} from '../utils/colors';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
import Modal from 'react-native-modal';
import Snackbar from 'react-native-snackbar';
import {duration} from 'moment';

const width = [Link]('window').width;

const API_BASE = '[Link]

Next, add the Axios calls to interact with the REST API provided via the Express web server to interact with the
MongoDB database.
642 11 • Web Applications Development

const [todos, setTodos] = useState([]);


const [modalActive, setModalActive] = useState(false);
const [newTodo, setNewTodo] = useState('');

useEffect(() => {
GetTodos();
}, [todos]);

const GetTodos = () => {


axios
.get(`${API_BASE}/api/todos`)
.then(response => {
setTodos([Link]);
})
.catch(err => {
[Link]('Error: ', err);
[Link]({
text: '' + err,
duration: Snackbar.LENGTH_LONG,
backgroundColor: 'red',
textColor: [Link],
});
});
};

const completeTodo = async id => {


const data = await [Link](`${API_BASE}/api/todos/${id}`);

setTodos(todos =>
[Link](todo => {
if (todo._id === data._id) {
[Link] = [Link];
}

return todo;
}),
);
};

const deleteTodo = async id => {


const data = await [Link](`${API_BASE}/api/todos/${id}`);

setTodos(todos => [Link](todo => todo._id !== data._id));


};

const addTodo = async () => {


if (newTodo == '') {
[Link]('Error!', 'Please enter a task first!');
return;
} else {

Access for free at [Link]


11.6 • Sample Ethereum Blockchain Web 2.0/Web 3.0 Application 643

await axios
.post(`${API_BASE}/todo/new`, {
text: newTodo,
})
.then(function (response) {
const data = [Link];
setTodos([...todos, data]);
setModalActive(false);
setNewTodo('');
})
.catch(function (error) {
[Link]('Error: ', error);
});
}
};

11.6 Sample Ethereum Blockchain Web 2.0/Web 3.0 Application


Learning Objectives
By the end of this section, you will be able to:
• Build a hybrid Ethereum blockchain Web 3.0 application
• Create the React app and install dependencies
• Create the smart contract
• Create the front-end React components
• Add Web3 to the React app
• Configure the React app to communicate with the smart contract

So far, this chapter has explored how to develop a Todo web application, as well as a Todo mobile application,
using Bootstrap, Django, React, React Native, and Node. In this final section, you will learn how to create a
simple Todo application using React with Web 3.0 powered by Ethereum smart contracts on the blockchain.

Creating a Todo Ethereum Blockchain Web 3.0 Application


As you have learned, Todo applications can be created using different tools. In this section, you will explore the
Ethereum blockchain, which creates a secure peer-to-peer network through the use of a smart contract,
which is a secure digital agreement that enables users to transact directly with each other via the blockchain.
You will use React to create a Todo Ethereum blockchain Web 3.0 application.

LINK TO LEARNING

Ganache ([Link] is a personal Ethereum blockchain environment that provides


developers with the means to use a private blockchain for development and testing. Ganache can emulate
the Ethereum blockchain, and because it is a private blockchain, it allows developers control over
development and testing processes.

Prerequisites
To build the Todo Ethereum blockchain Web 3.0 application, you should use React v17.0.2, Bootstrap v4.5.0,
Node v14.17.5, Web [Link] v1.2.2, Truffle v5.0.2, and Solidity v0.8.11. In addition, Ganache is used as the personal
blockchain for development. To begin, do the following:
644 11 • Web Applications Development

• Download and install Ganache. Launch Ganache and choose the quick start Ethereum option as seen in
Figure 11.46.

Figure 11.46 This is the quick start Ethereum option that is available after installing Ganache. (credit: Ganache, under MIT
license)

• The next step is to install the MetaMask Chrome plug-in. Configure the MetaMask account and log in.

Creating the React App


Previously in this chapter, you created React apps. For this application, you need to create a new React app.

To create the new React app, run the following command:

$ npx create-react-app ethreact

Install Bootstrap, Web3, and Other Dependencies


To use Bootstrap and Web3 in a React app, corresponding packages must be installed. To do this, in the
ethreact/ directory, run the following commands:

$ npm install bootstrap@4.6.0 reactstrap@8.9.0 --legacy-peer-deps


$ npm install react-bootstrap
$ npm install web3@1.2.2

Next, import the Bootstrap CSS file into the React application. Open ethreact/src/[Link] and add the following
Bootstrap import.

import React from 'react';


import ReactDOM from 'react-dom';

Access for free at [Link]


11.6 • Sample Ethereum Blockchain Web 2.0/Web 3.0 Application 645

import 'bootstrap/dist/css/[Link]';
import './[Link]';
import App from './App';
import reportWebVitals from './reportWebVitals';

[Link](
<[Link]> <App /> </[Link]>,
[Link]('root')
);

// If you want to start measuring performance in your app, pass a function


// to log results (for example: reportWebVitals([Link]))
// or send to an analytics endpoint. Learn more: [Link]
reportWebVitals();

LINK TO LEARNING

Truffle ([Link] provides a suite of tools that can be used to develop smart
contracts. Truffle offers end-to-end development that includes the ability to develop, test, and implement
smart contracts, while using Truffle to manage the workflow.

Creating the Smart Contract


To develop the Ethereum smart contract, you will use the Truffle Framework, which is a popular suite of tools
used to develop smart contracts. Implement the Truffle Framework using Solidity, which is a high-level, object-
oriented language that is focused on the implementation of smart contracts. To use the Truffle Framework, in
the ethreact/ directory, run the installation following command:

$ npm install -g truffle@5.0.2

To set up the React app to use Truffle, in the ethreact/ directory, run the following command, which may take
several minutes.

$ truffle init

When the initialization is completed, the contracts/ directory and [Link] file will be generated. In
addition, the [Link] file will be generated, as highlighted in Figure 11.47.
646 11 • Web Applications Development

Figure 11.47 Here is the [Link] file. (rendered with Truffle by Truffle Security Co., under MIT license; attribution: Copyright
Rice University, OpenStax, under CC BY 4.0 license)

To create the smart contract, in the ethreact/contracts/ directory, create the file [Link] and add the
following code.

pragma solidity ^0.5.0;


contract TodoList {
uint public taskCount = 0;

struct Task {
uint id;
string content;
bool completed;
}

mapping(uint => Task) public tasks;

event TaskCreated(
uint id,
string content,
bool completed
);

event TaskCompleted(
uint id,
bool completed

Access for free at [Link]


11.6 • Sample Ethereum Blockchain Web 2.0/Web 3.0 Application 647

);

constructor () public {
createTask("Check out [Link]");
}

function createTask(string memory _content) public {


taskCount ++;
tasks[taskCount] = Task(taskCount, _content, false);
emit TaskCreated(taskCount, _content, false);
}
function toggleCompleted(uint _id) public {
Task memory _task = tasks[_id];
_task.completed = !_task.completed;
tasks[_id] = _task;
emit TaskCompleted(_id, _task.completed);
}

Next, compile the smart contract. In the ethreact/ directory, run the following command:

$ truffle compile

This command should provide a status confirming that the smart contract has been successfully compiled as
seen in the following code:

> Compiled successfully using:


- solc: 0.5.16+[Link]

Figure 11.48 shows how this process will generate a few files, including two JSON files in the build/contracts/
directory and a migration file in the migrations/ directory.

Figure 11.48 These are the JSON and migration files generated when the smart contract is compiled. (rendered using JSON;
attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)

The [Link] file in the build/contracts/ directory is the smart contract Abstract Binary Interface (ABI) file.
This file contains the following:
648 11 • Web Applications Development

• compiled bytecode from the Solidity smart contract code that can run on the Ethereum Virtual Machine
(EVM)
• a JSON representation of the smart contract.

Next, configure the React app to connect to the Ganache blockchain network. To do this, open the ethreact/
[Link] file and uncomment the two sections shown. Under “networks,” enable the connection host
and port to the Ganache blockchain network. Ensure that the host and port are in sync with the following
settings in Ganache.

development: {
host: "[Link]", // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},

Next, under “compilers,” enable the solc optimizer.

// Configure your compilers


compilers: {
solc: {
// version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's
version)
// docker: true, // Use "0.5.1" you've installed locally with docker
(default: false)
// settings: { // See the solidity docs for advice about optimization and
evmVersion
optimizer: {
enabled: true,
runs: 200
},
// evmVersion: "byzantium"
// }
}
},

Next, create a migration script to deploy the smart contract to the Ganache blockchain network. In the
ethreact/migrations/ directory, create the file 2_deploy_contracts.js and add the following code.

var TodoList = [Link]("./[Link]");

[Link] = function(deployer) {
[Link](TodoList);
};

The next step is to migrate the contract. In the ethreact/ directory, run this command.

$ truffle migrate

Figure 11.49 displays how the contract will be migrated and provides the transaction details. You should make
a note of the contract address in the output because it will be added to the [Link] file later.

Access for free at [Link]


11.6 • Sample Ethereum Blockchain Web 2.0/Web 3.0 Application 649

Figure 11.49 Here are the transaction details for migrating the contract. (attribution: Copyright Rice University, OpenStax, under CC
BY 4.0 license)

LINK TO LEARNING

Solidity is a high-level, object-oriented language used to implement smart contracts. Influenced by


JavaScript, C++, and Python, Solidity is focused on the Ethereum Virtual Machine. Smart contracts
implemented by Solidity are used for purposes like blind auctions, voting, and crowdfunding. Visit this page
on Solidity ([Link] to learn more.

Creating the Front-End React Components


The TodoList component renders the user interface for the Todo app. In the ethreact/src/ directory, create the
components/ directory. In the components/ directory, create the file [Link] and then create the TodoList
component.

import React, { Component } from 'react'

class TodoList extends Component {

render() {
return (
<div id="content"> <form => {
[Link]() [Link]([Link])
}}> <input id="newTask" ref={(input) => {
[Link] = input }} type="text"
className="form-control" placeholder="Add task..."
required /> <input type="submit" hidden={true} />
</form> <ul id="taskList" className="list-unstyled"> {
[Link]((task, key) => { return( <div
className="taskTemplate" className="checkbox" key={key}> <label>
<input type="checkbox"
name={[Link]} defaultChecked={[Link]}
650 11 • Web Applications Development

ref={(input) => { [Link] = input


}} => {
[Link]([Link]) }}/>
<span className="content">{[Link]}</span>
</label> </div> ) })}
</ul> <ul id="completedTaskList" className="list-unstyled">
</ul> </div>
);
}
}
export default TodoList;

Update the ethreact/src/[Link] to import and render the TodoList component.

render() {
return (
<div> <nav className="navbar navbar-dark fixed-top bg-dark flex-md-nowrap
p-0 shadow"> <a className="navbar-brand col-sm-3 col-md-2 mr-0"
href="#">ToDo</a> <ul className="navbar-nav px-3"> <li
className="nav-item text-nowrap d-none d-sm-none d-sm-block"> <small><a
className="nav-link" href="#"><span id="account"></span></a></small> </li>
</ul> </nav> <div className="container-fluid"> <div
className="row"> <main role="main" className="col-lg-12 d-flex justify-
content-center"> { [Link] ? <div id="loader"
className="text-center"><p className="text-center">Loading...</p></div>
: <TodoList tasks={[Link]}
createTask={[Link]}
toggleCompleted={[Link]} /> }
</main> </div> </div> </div>
);
}

Adding Web3 to the React App


The next step is to add Web3 and configure it to connect to Ganache. To do this, open ethreact/src/[Link],
import the Web3 package, and add the code shown here. In this code, a web3 connection is instantiated
providing the Ganache URL ([Link] This enables the React app to connect to the blockchain.
The blockchain account information is then accessed and added to the React app’s state object. In the
ethreact/src/ directory, create the file [Link] and add the code shown. This code creates a Web3 object via
different connection approaches depending on the approach used (e.g., type of DApp browser, using
localhost).

import Web3 from "web3";

const getWeb3 = () =>


new Promise((resolve, reject) => {
// Wait for loading completion to avoid race conditions with web3 injection
timing.
[Link]("load", async () => {
// Modern dapp browsers...
if ([Link]) {

Access for free at [Link]


11.6 • Sample Ethereum Blockchain Web 2.0/Web 3.0 Application 651

const web3 = new Web3([Link]);


try {
// Request account access if needed
await [Link]();
// Accounts now exposed
resolve(web3);
} catch (error) {
reject(error);
}
}
// Legacy dapp browsers...
else if (window.web3) {
// Use Mist/MetaMask's provider.
//const web3 = window.web3; // ORIG
const web3 = [Link]()
[Link]("Injected web3 detected.");
resolve(web3);
}
// Fallback to localhost; use dev console port by default...
else {
const provider = new [Link](
"[Link]
);
const web3 = new Web3(provider);
[Link]("No web3 instance injected, using Local web3.");
resolve(web3);
}
});
});

export default getWeb3;

Configuring the React App to Communicate with the Smart Contract


To make the tasks from the smart contract available to the React app, create a config file, along with the
contract address and ABI. To do this, in the ethreact/src/ directory, create the file [Link]. Then, create two
variables: TODO_LIST_ADDRESS and TODO_LIST_ABI. Grab the contract address that was provided when the
smart contract was deployed to the blockchain and assign it to TODO_LIST_ADDRESS. Open the ethreact/build/
contracts/[Link] file and copy the ABI portion only and assign it to TODO_LIST_ABI.

export const TODO_LIST_ADDRESS = '0x9A93A9951c1cAcF0Cecc320Fa6aD4e05d55a2d02'

export const TODO_LIST_ABI = [


{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
652 11 • Web Applications Development

"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bool",
"name": "completed",
"type": "bool"
}
],
"name": "TaskCompleted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "string",
"name": "content",
"type": "string"
},
{
"indexed": false,
"internalType": "bool",
"name": "completed",
"type": "bool"
}
],
"name": "TaskCreated",
"type": "event"
},
{
"constant": true,
"inputs": [],
"name": "taskCount",
"outputs": [
{
"internalType": "uint256",
"name": "",

Access for free at [Link]


11.6 • Sample Ethereum Blockchain Web 2.0/Web 3.0 Application 653

"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "tasks",
"outputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "string",
"name": "content",
"type": "string"
},
{
"internalType": "bool",
"name": "completed",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "string",
"name": "_content",
"type": "string"
}
],
"name": "createTask",
"outputs": [],
"payable": false,
654 11 • Web Applications Development

"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "_id",
"type": "uint256"
}
],
"name": "toggleCompleted",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
]

Next, update ethreact/src/[Link]. Import [Link] and add the following code to the
componentDidMount() life cycle method. This will connect to the blockchain network and load the contract
before the React components renders in the browser.

componentDidMount = async () => {


try {
// Get network provider and web3 instance.
const web3 = await getWeb3();

// Use web3 to get the user's accounts.


const accounts = await [Link]();

// Get the contract instance.


const networkId = await [Link]();
let deployedNetwork = [Link][networkId];
const todoListInstance = new [Link](
TODO_LIST_ABI,
deployedNetwork && [Link]
);

// Set web3, accounts, and contract to the state, and then proceed with an
// example of interacting with the contract's methods.
[Link]({ web3, accounts, todoListContract: todoListInstance },
[Link]);
} catch (error) {
// Catch any errors for any of the above operations.
alert(
'Failed to load web3, accounts, or contract. Check console for details.',
);
[Link](error);

Access for free at [Link]

You might also like