All About Progressive Web Applications and NewSQL - ByteScout
  • Home
  • /
  • Blog
  • /
  • All About Progressive Web Applications and NewSQL

All About Progressive Web Applications and NewSQL

The point of progressive web apps is to make optimal use of the ever-evolving capabilities of browsers. One such advanced browser capability is to store data in a browser for offline app functionality. Browsers now use several NoSQL and NewSQL technologies for this purpose.

Apache Ignite, and Google Spanner DB are popular NewSQL DBs. MySQL Cluster is an optimized and highly scalable new SQL interface. Offline DB management is the focus of our ultimate tutorial today, and we’ll look at several code examples to illustrate the best methods.

While the focus of our ultimate progressive web application development tutorial is NoSQL for offline core content data storage, we need to lay some groundwork.

Before we delve deeper into NoSQL DB features, such as NoSQL document storage, let’s explore the tangibles of PWAs to create a context and motivation for offline DB management. As mentioned, the PWAs represent an ideal to leverage every available new technology in web design.

Service Workers and Web Manifests provide much of the functionality toward reaching these ideals. Developers are now empowered to build PWAs with features including:

  • Service Workers – provide offline functionality.
  • Web manifests – specify device display and other info.
  • Push notifications – server-initiated transactions.
  • Progressive enhancement – core page content works for all users.
  • HTTPS – transactions run through secure encryption.
  • Linking – access through URL is easier than installation.

Service Workers Work Miracles

Mobile apps and web apps compete for supremacy, but each has a limiting set of inherent advantages and disadvantages.

Mobile apps offer higher performance and richer user experience, but the costs are reduced real-time interactivity and pressure on limited device storage.

Web apps are highly interactive in real-time, but also highly dependent on Internet connectivity and speed. Service Workers arise as a solution to resolve the disadvantages, especially of the web apps. Service workers improve web app performance with the following enhancements:

  • Event-driven rather than document driven
  • Background synchronization of data/content
  • Push notification handling

Mechanically, service workers sit between server and device to manage requests and supply content. The service worker functions as network proxy in browsers to manage HTTP requests.

Ultimately service workers provide the mechanism for efficient cache use which makes offline functionality possible.

Manifestly Improved

The web manifest includes metadata for a web app and is a valuable JSON container which exposes linking and content to search. Manifests make it possible to deposit a web app’s icon on a device home screen alongside installed apps!

From the user’s point of view, the web app operates like a native mobile app. And the offline functionality, we will soon discover, is a crucial part of this user experience. Important metadata stored in a manifest includes:

  • Web app name
  • Links to the app’s icon images
  • The app’s launch URL
  • Configuration and settings params

As you can imagine, the manifest essentially converts a bookmark into a native app on a device’s home screen. This looks to the user just like an installed app.

If the web app then performs accordingly, there is no essential difference. Coding for offline work goes a long way toward achieving the necessary performance!

Pushy Push Notifications

Central to creating an app-like feel in progressive web apps is push technology. Push notifications are subscribe-publish interaction in which the server initiates a transaction.

The capability of the app host server to initiate action which is then executed on a device is much more interactive.

The real-time interactivity achieved with push notifications gives the web app more autonomy than with apps which rely solely on one-sided pull requests. Push requests update an app’s page display automatically.

Progressive Enhancement

As with the overall concept of PWAs, progressive enhancement is a guiding architectural principle, rather than a specific technology. But building pages according to this principle is definitely facilitated by specific technologies.

The primary goal here is to ensure that the core functionality and core website content of a page are accessible to all browsers.

Ensuring core functionality on all browsers is not a trivial pursuit. It effectively requires a survey of technologies supported by all browsers before the first line of code can be written!

Compliance, in other words, is often more difficult to guarantee in the scope of new technologies. Other targets of progressive enhancement include:

  • Complete external CSS layout
  • More advanced features are lined external JavaScript
  • Compliance with client browser preferences

When core page content works for all users across all browsers, a web app has a standard metric. End users report similar and consistent results.

HTTPS & Linking

To wrap up our survey of PWAs and motivate our NewSQL exploration, we just need to mention the benefits of security and linking. These are characteristic advantages of web apps over native apps rather than coding methods.

Because web apps run transactions through HTTPS, the encryption makes them more secure than native apps.

Finally, linking an icon on the home screen to the URL of a web app will save a lot of storage space over installed apps for mobile devices, especially as the number of apps grows.

The NoSQL DB Emphasis

Now that we have defined the objectives of PWAs, it’s time to bite off one of the major chunks and really dig into it. We’re talking about the offline database for progressive web app development.

  • Adding a service worker for offline functionality
  • Using Cache API in a PWA
  • Creating a Google Spanner DB
  • Using Indexed database (IDB)

Adding a service worker

Given the progressive enhancement goal, you may find it ironic that ServiceWorker is not supported by all browsers yet. It likely will achieve global support, so we will press onward.

To achieve offline performance in a PWA, we need to learn how to integrate service workers into our applications.

To add a ServiceWorker your site must use a secure HTTPS connection. We will implement a simple website with static HTML, a CSS file, and a JavaScript file with a few images, and add offline support.

First, we will register the ServiceWorker. We pass a JavaScript resource to .register which will execute in the ServiceWorker context. Registration returns a promise, which makes it possible to track successful or failed registration. Have a look at this example of ServiceWorker registration:

  if('serviceWorker' in navigator) {
    console.log('thisCLIENT: Registration in progress..');
    navigator.serviceWorker.register('/service-worker.js').then(function() {
      console.log('thisCLIENT: Registration complete.');
    }, function() {
      console.log('thisCLIENT: Registration failed.');
    });
  } else {
    console.log('thisCLIENT: ServiceWorker not supported.');
  }

The ServiceWorker script generally originates from the host’s domain root folder. If the user’s browser supports ServiceWorker, it will send a request for /service-worker.js and try to install it. ServiceWorkers are event-driven which means that your app code should be stateless. When a ServiceWorker is inactive it is shut down. Do not code any memory state dependencies. To install the ServiceWorker include this script:

self.addEventListener("thisInstallation", function(event) {
  console.log('WORKER: installation event in progress.');
  event.waitUntil(
      /* Add caches as built-in promise API   */
    caches
      .open(version + 'fundamentals')
      .then(function(cache) {
      return cache.addAll([
          '/',
          '/css/globals.css',
          '/js/globals.js'
        ]);
      })
      .then(function() {
        console.log('WORKER: installation complete');
      })
  );
});

Cached content is now available to be served in offline mode. The ServiceWorker caches all designated content for offline use.

Creating a Google Spanner DB

For our illustration on creating a Spanner DB for offline database management, we will use PHP. Most developers are familiar with sending SQL queries through PHP scripts.

So, this will have a familiar feel. Spanner also supports API calls for most popular languages. Here, we’ll step through the use of Cloud Spanner client library.

The first step is to create a Cloud Spanner instance along with a database. We will illustrate how to write to the DB, run SQL queries on the data.

The code sample below will demo how to update the database schema, as well as how to update data with read-write transactions. This function example shows the syntax which will easy translate from SQL:

function create_myDatabase($instanceId, $databaseId)
{
    $spanner1 = new SpannerClient();
    $instance1 = $spanner->instance($instanceId);
    if (!$instance1->exists()) {
        throw new \LogicException("Instance $instanceId not exist");
    }
    $operation1 = $instance1->createDatabase($databaseId, ['statements' => [
        "CREATE TABLE tbl_Artists (
            ArtistId     INT32 NOT NULL,
            FirstName    STRING(25),
            LastName     STRING(25),
            ArtistsInfo   BYTES(MAX)
        ) PRIMARY KEY (ArtistId)",
        "CREATE TABLE Albums (
            ArtistId     INT32 NOT NULL,
            AlbumId      INT32 NOT NULL,
            myAlbumTitle   STRING(MAX)
        ) PRIMARY KEY (ArtistId, AlbumId),
        INTERLEAVE IN PARENT tbl_Artists ON DELETE CASCADE"
    ]]);

Spanner supports adding a secondary key index to a table. This makes possible using the index to run SQL queries on your data. Here is an example of how to run a query in Spanner:

$database = $instance1->database($databaseId);
$results = $database->execute('SELECT "Hello World" as test');
foreach ($results as $row) {
    print($row['test'] . PHP_EOL);
}

And inserting data to a table is easy to do with this sample function:

function insert_myData($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance1 = $spanner->instance1($instanceId);
    $database = $instance1->database($databaseId);

    $operation = $database->transaction(['singleUse' => true])
        ->insertBatch('Artists', [
            ['ArtistId' => 1, 'FirstName' => 'MarK', 'LastName' => 'Herbertson']
          …
}

Altering database schema is easy with Spanner. To add a new column to a table requires a schema update.

Cloud Spanner supports updating a database schema even while the database is online serving requests and queries! Schema updates do not require the database to be offline, and do not even need to lock tables!

This is an extraordinary feature for PWA performance because it dramatically reduces app maintenance downtime. Undoubtedly, this is one of the premium features which enterprises will pay for: Cloud Spanner is not free, a departure from the Google norm.

Cache API for PWAs

The purpose of Cache API is to store and retrieve network requests and responses. The work of Cache API falls into two main categories.

The Cache API system can store ordinary requests and responses which occur during the execution of a web app.

Cache API can also store data for the sole purpose of maintaining the data in the cache for offline use.

In particular, Cache API enables a ServiceWorker to cache network requests in order to respond even when the web app is offline. But crucially the cache can also be used as a general storage for offline data and content.

A Firefox cache, for example, can use 10% of available space! Following is a basic example to set up with Cache API. The first step creates a Request object using a URL for the object to be stored:

const request = new Request('/images/picture1.jpg');

const myImageBlob = new Blob([data], {type: 'image/jpeg'});

const myImageResponse = new Response(myImageBlob);

const ThisStringResponse = new Response('Hello PWA World!!!);

Above, the Response object constructor will accept a variety of data types. Common types used include ArrayBuffers, strings, Blobs, FormData, and more. Google’s Cache API NoSQL documentation contains a complete reference on Response objects. The core knowledge is available for PWA progressive web app development.

IndexedDB for PWAs

An Indexed database (IDB) is a type of NoSQL database which makes it easy for a web app to display content even when running in offline mode. IDB is perhaps the most popular and standard way to store data through a browser.

The web browser standard interface does transactions on the local database. IDB uses a collection of indexed JSON objects for this client-side database management. And this is contrasted with the typical MySQL database, where the data store resides on the server.

IndexedDB is a low-level type language API for coding client-side database management. IDB is ideal for storing large datasets – perfect for Big Data –  and large structured data sets. IDB’s API uses indexes to power high-performance searches.

IndexedDB is specifically a transactional database system. The interface resembles SQL. But IndexedDB is JavaScript-based. And it is object-oriented, unlike SQL (however, see our PostgreSQL tutorial for an object-oriented version of SQL).

While SQL uses tables with fixed-columns, IndexedDB stores object indexed with a key instead. The structured clone algorithm (SCA) dictates the type of content which can be indexed.

In the next code example, we will illustrate how to open a DB, specify the database schema, and open a connection to the IndexedDB. Then we will simply retrieve and display data saved persistently in the browser:

var request = window.indexedDB.open("ThisTestDatabase", 3);
var db1;
var request = indexedDB.open("ThisTestDatabase");
request.onerror = function(event) {
  alert("IndexedDB not supported on this browser");
};
request.onsuccess = function(event) {
  db1 = event.target.result;
};
var objectStore1 = transaction.objectStore("customers");
customerData.forEach(function(customerdb) {
  var request = objectStore.add(customerdb);
  request.onsuccess = function(event) {
    // event.target.result === customerdb.ssn;
  };

ACID Compliance

NewSQL and NoSQL technologies do not comply with the rigorous ACID standards. This means that PWA development reveals a challenge to other idealized methods which enterprise developers follow as guiding lights. ACID is one such beacon to be challenged SQL DB platforms. So, let’s review ACID and see where PWA development does not comply.

  • Atomicity requires that transactions are complete 100% or fail 100%. A partially complete transaction will not be entered.
  • Consistency means that a database can only change state if the transition is from one valid state to another valid state.
  • Isolation demands that transactions which run asynchronously have a final result equivalent to the serial execution of the same set.
  • Durability guarantees that a committed transaction is permanent. This protects the DB against machine failure and even power failure.

Reading this strictly, it is clear that even the best NoSQL database platforms cannot enforce compliance with these ideals. NoSQL database use cases individually show variation, as enterprises develop coding standards to emulate compliance in various degrees.

Inevitable PWAs

In performance races between native mobile apps and web apps which load in browsers native apps previously dominated the cyberscape. They loaded faster and were optimized for mobile. But nowadays, thanks to AJAX and its spawn such as AngularJS, dynamic and progressive apps are in the race again. In this tutorial, we learned how to build a PWA and leverage a NewSQL database.

We have seen how guiding principles and extended functionality define the architecture of progressive web development.

The objective is to exploit every technological innovation in browsers today. The nuances and advantages leveraged by PWAs include service workers, push notifications, progressive enhancement design ideology, and much more.

We hope you will continue your study of PWA apps by building your own examples. And don’t forget to tune in next week for the next Bytescout ultimate tutorial.

 

About the Author

Author Mark

Mark Ronald Moore

Mark is a freelance consultant and coder in the areas of machine learning, automation testing, and web app development. He currently writes coding tutorials and tech articles regularly for ByteScout. Mark is a resident of Humboldt, California, and enjoys hiking in the redwoods.

 

 



prev
next