Isomorphic Go

3.3 (3 reviews total)
By Kamesh Balasubramanian
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Isomorphic Web Applications with Go

About this book

Isomorphic Go is the methodology to create isomorphic web applications using the Go programming language. Isomorphic web applications have the capability to reuse code across environments, increasing the synergy between the web server and the web browser. This book is a hands-on guide that will show you how to build and deploy an Isomorphic Go web application.

Isomorphic Go begins with an in-depth exploration of the benefits provided by the isomorphic web application architecture. You'll be introduced to the Isomorphic Go toolchain, and how it can help you write Go code that functions across environments. You'll learn how to create Go programs in the web browser using GopherJS and how to render isomorphic templates. Then you'll be introduced to end-to-end application routing, use isomorphic handoff to seamlessly transition state from the web server to the web browser, and compose isomorphic forms that have the ability to reuse form validation logic. You'll be exposed to advanced concepts including the implementation of real-time web application functionality with websockets and the creation of reusable components (cogs) that are rendered using the virtual DOM. Finally, you'll see how to deploy an Isomorphic Go web application to a production environment.

Publication date:
December 2017
Publisher
Packt
Pages
516
ISBN
9781788394185

 

Chapter 1. Isomorphic Web Applications with Go

Isomorphic web applications, are applications where the web server and the web browser (the client), may share all, or some parts of the web application code. Isomorphic web applications allow us to reap maximum benefits from traditional web application architectures. They provide a better user experience, enhanced discoverability by search engines, and reduced operating costs by sharing parts of the web application code across environments.

Well-established businesses, such as Airbnb, Bloomberg, Capital One, Facebook, Google, Netflix, and Walmart have accepted isomorphic web application development, and with good reason—the financial bottom line.

A study by Walmart found that for every 1 second of improvement, they experienced up to a 2% increase in conversions. In addition to that, they also found that for every 100 milliseconds of improvement, they grew incremental revenue by up to 1%. Source: How Website Speed Affects Conversion Rates (http://www.globaldots.com/how-website-speed-affects-conversion-rates/).

Isomorphic Go is the methodology to create isomorphic web applications using the Go programming language. In this book, we will explore, in-depth, the process of creating an isomorphic web application in Go.

This chapter will cover the following topics:

  • Why you should consider isomorphic Go for developing modern web applications
  • An overview of the traditional web application architectures
  • An introduction to the isomorphic web application architecture
  • When to implement isomorphic web applications
  • What you should know before learning Isomorphic Go
 

Why Isomorphic Go?


There is no doubt that JavaScript is the current leading technology, in terms of market share and mindshare, for creating isomorphic web applications. On the client-side, JavaScript comes included with all the major web browsers. JavaScript can now, also exist on the server side, thanks to Node.js.

If this is the case, then why should we focus our attention on Go for creating isomorphic web applications? The answer to this question is manifold. Consider the list of answers provided here, as an initial list, which is the starting point for our discussion:

  • Go comes with type checking
  • Even the tech giants avoid Vanilla JavaScript
  • Transpiling code to Vanilla JavaScript has become widely accepted
  • Go comes with a lot of benefits for front-end web development

Go comes with type checking

Go is a language that includes built-in static type checking. The immediate ramification of this fact is that many errors can be caught at compile time itself.

The single-most pain point for many JavaScript developers is the lack of static type checking in JavaScript. Having personally worked in JavaScript code bases that have spanned several hundred thousand lines of code, I have seen first hand, how the most trivial bug can arise from the lack of static type checking.

Avoiding Vanilla JavaScript with transpilers

To avoid writing Vanilla JavaScript, tech giants Microsoft and Google, have created TypeScript and Dart, respectively, as languages and transpilers. A transpiler is a source code to source code compiler.

A compiler will turn human readable code, written in a programming language, into machine code. A transpiler is used to transform source code from one programming language into that of another language. The output may or may not be readable by a human, depending on the intent of the transpiler.

Languages, such as Typescript and Dart, get transpiled into Vanilla JavaScript code, so that they can be run in JavaScript-enabled web browsers. In the case of TypeScript, it's essentially a superset of JavaScript that introduces static type checking. The creators of the AngularJS Framework chose TypeScript over Vanilla JavaScript as the language of choice, to develop the next major version of their framework.

This approach to side stepping JavaScript, using an alternative programming language and a transpiler, creates a win-win situation for the developer. The developer is allowed to program in a programming language that is most productive for them and, at the end of the day, the code the developer created, is guaranteed to run in the web browser—thanks to the transpiler.

Transpiling code

Transpiling code to JavaScript, has become a widely accepted practice, even within the JavaScript community itself. For instance, the Babel transpiler allows developers to code in yet-to-be-released future standards of the JavaScript language, which get transpiled into the widely accepted standard JavaScript code that's currently supported in the major web browsers.

Within this context, it is not outlandish, or far-fetched, to run Go programs, that get transpiled into JavaScript code, in the web browser. In fact, besides static type checking, there are many more benefits to be gained from being able to run Go on the front-end.

Benefits of Go on the front-end

Having Go available on the front-end comes with many advantages, including the following:

  • A robust standard library
  • Code modularization is easy with Go packages
  • Go comes with an implicit build system
  • Go's concurrency constructs allow us to avoid callback hell
  • The concept of concurrency comes built-in with Go
  • Go can be utilized for isomorphic web application development

Robust standard library

Go comes with a robust standard library that provides a lot of powerful functionality out of the box. For instance, in Go, we can render an inline client-side template without having to include any third-party template library or framework. We will consider an example of how to do this in Chapter 3, Go on the Front-End with GopherJS.

Promoting modularization using Go packages

Go has a powerful package implementation that promotes modularization, allowing for far greater code-reuse and maintainability. Also, the Go tool chain includes the go get command, which allows us to easily fetch official and third-party Go packages.

Note

If you're coming from the JavaScript world, think of go get as a more simple, lightweight npm (npm is the Node Package Manager, a repository of third-party JavaScript packages).

An implicit build system

In the JavaScript ecosystem, it is still popular, in modern times, for developers to spend their time manually creating and maintaining project build files. Being a modern programming language, Go ships with an implicit build system.

As long as you follow Go's prescribed conventions, and once you issue the go build command for your Go application, the implicit build system kicks in. It will build and compile the Go project automatically by examining the dependencies it finds, within the application's Go source code itself. This provides a major productivity boost for the developer.

Avoiding callback hell

Perhaps the most compelling reason to consider Go for isomorphic web development is to avoid callback hell. JavaScript is a single threaded programming language. When we want to delay the execution of a particular task after an asynchronous call has been made, we would place the code for those tasks inside a callback function.

Soon enough, our list of tasks to delay for execution will grow, and the amount of nested callback functions will grow along with it. This situation is known as callback hell.

We can avoid callback hell in Go, using Go's built-in concurrency constructs.

Concurrency

Go is a modern programming language designed to be relevant in an age of multicore processors and distributed systems. It was designed in a manner where the importance of concurrency was not treated as an afterthought.

In fact, concurrency was so important to the creators of Go, that they built concurrency right into the language itself. In Go, we can avoid callback hell, using Go's built-in concurrency constructs: goroutines and channels. Goroutines are cheap, lightweight threads. Channels, are the conduits that allow for communication between goroutines.

Isomorphic web application development using Go

When it comes to isomorphic web application development, JavaScript is no longer the only game in town. Due to recent technological advancements, notably the creation of GopherJS, we can now use the Go programming language on the front-end; this allows us to create isomorphic web applications in Go.

Isomorphic Go is an emerging technology that provides us the essential ingredients needed to create isomorphic web applications, using the powerful and productive features that the Go programming language has to offer. In this book, we will use the functionality from Go's standard library and third-party libraries from the Go community to implement an isomorphic web application.

 

An overview of web application architectures


In order to understand and fully appreciate the architecture of isomorphic web applications, it's insightful to have an understanding of the web application architectures that preceded it. We will cover the major web application architectures that have been prevalent in the industry over the past 25 years.

After all, we can't truly appreciate where we have arrived at, until we've fully acknowledged where we have been. With the monumental changes that have occurred in the web application architecture realm over the years, there is much to acknowledge.

Before we present the isomorphic web application architecture, let's devote some time to review the three traditional web application architectures that came before it:

  • The classic web application architecture
  • The AJAX web application architecture
  • The single-page application (SPA) architecture

We'll identify the advantages and disadvantages for each of the three architectures considered. We will start a wish list of requirements, based on each disadvantage that we identify for a given architecture. After all, a shortcoming is actually an opportunity for improvement.

 

The classic web application architecture


The classic web application architecture dates back to the early 1990s, when graphical web browsers started to gain traction. When the user interacts with a web server using a web browser, each user interaction, makes a request to a web server using HTTP. Figure 1.1 depicts the classic web application architecture:

Figure 1.1: The Classic Web Application Architecture

The diagram also depicts an HTTP transaction, which consists of a request that's sent from the user's web browser to the web server. Once the web server accepts the request, it will return a corresponding response for that request.

Typically, the response is an HTML web page, which may either contain inline CSS and/or JavaScript, or call external CSS stylesheets and/or JavaScript source files.

Note

There are two types of resources that the web server can return in the form of a response: a static resource and a dynamic resource.

A static resource is a file. For example, it could be an HTML, JPEG, PDF, or MP4 file that lives on the web server. The server will return the document specified by the request in its response body.

A dynamic resource is a resource that gets built by the server on the fly. An example of a dynamic resource is a search engine's search results page. Usually, the response body of a dynamic request will be formatted in HTML.

When it comes to web applications, we deal with dynamic resources. The web server is serving a web application, and usually the web application contains a controller with the logic that routes the user's request to a specific action to perform on the server. Once the web server is done processing the user's request, the server sends a response back to the client in the form of a web page response.

A server-side programming language (such as Go, Perl, PHP, Python, Ruby, and Java) is used to process the requests sent from the web browser. For example, let's consider we have a server side web application that is used for an e-commerce website.

The web application can route requests by making use of a server-side route handler (as shown in Figure 1.1); the /product-detail/swiss-army-knife route can be associated to a product detail controller, which will serve an HTML web page response containing the product profile page for the Swiss Army Knife product.

In a classic web application architecture, the code to render the web page lives on the server side, typically consolidated into template files. Rendering the web page response from a set of templates is performed by the template renderer that resides on the server (as shown in Figure 1.1).

Usually in this paradigm, JavaScript may be included in a rendered web page to enhance the user experience. In this type of web application architecture, the responsibility of implementing the web application is placed primarily on the server-side language, and JavaScript is placed on the sidelines of being used primarily for user interface controls or enhanced user interactivity for the website.

Advantages

The classic web application architecture comes with two major advantages:

  • Faster initial page loads
  • Greater search engine discoverability

Faster initial page loads

The first primary advantage of the classic web application architecture is that page loads are perceived to be fast by the user since the entire page is rendered at once. This is a result of the web server rendering the web page response, using a template renderer, on the server side itself.

The user does not perceive slowness, since they are delivered the rendered page from the server instantaneously.

Note

Keep in mind that if there is high latency in the server's response time, then the user interaction will come to a grinding halt. In this scenario, the fast initial page load advantage is lost since the user has to stare at a blank screen—waiting for the server to finish processing. This waiting will end with either the web page response being delivered to the user, or the HTTP request timing out—whichever comes first.

Greater search engine discoverability

The second primary advantage of the classic web application architecture is that this architecture is search engine friendly, since the web application serves up web page responses, in HTML, that can be readily consumed by search engine bots. In addition to this, the server-side route-handler allows for the creation of search engine friendly URLs, that can be associated with a specific server-side controller.

A key factor to making a website friendly to search engines is discoverability. Besides having great content, a search engine friendly website also needs permalinks – web links that are intended to remain in service permanently. Descriptive and well-named URLs can be registered as routes with the server-side's router. These routes end up serving as permalinks, which the search engine bot crawlers can easily index while crawling through the website.

The goal is to have pretty website URLs that can contain meaningful information, which can be easily indexed by a search engine's bot crawler, such as: http://igweb.kamesh.com/product-detail/swiss-army-knife.

The aforementioned permalink is much more easily indexed by a search engine and understood by a human rather than the following one: http://igweb.kamesh.com/webapp?section=product-detail&product_id=052486.

The primary disadvantage

We'll be examining the primary disadvantage(s) for each of the traditional web application architectures considered in this chapter. The isomorphic web application architecture section in this chapter, will show us how the isomorphic web application architecture provides a solution for each disadvantage presented and also gather the benefits offered from each of the traditional web application architectures.

The primary disadvantage of the classic web application architecture is that all user interactions, even the most trivial, require a full page reload.

This means that the Document Object Model (DOM), the tree data structure representing the current state of the web page, and the elements that comprise it, are completely wiped out, and recreated again upon each user interaction:

Figure 1.2: A layout diagram of a news website with a comments section and a wireframe depicting the comments section

For example, let's consider that we are reading an article on a news website. Figure 1.2, depicts a layout diagram of the news website (the illustration on the left), with the comments section of the website at the bottom of the web page. Other sections may exist on the news website in the negative (empty) space in the layout.

Figure 1.2 also includes a wireframe design of the news comments section (the illustration on the right), which contains a few sample comments. The ellipses (...) denotes multiple website comments that are not listed for the sake of brevity.

Let's consider scenario where this particular news article has gone viral and it contains more than 10,000 comments. The comments are paginated, and there are 50 comments displayed per page:

Figure 1.3: The entire web page needs to be refreshed to view the next set of comments

Figure 1.3 depicts the web page for the news website being refreshed (the illustration on the left). Note that the user will perceive the refresh to be quick because the page will instantaneously load (considering that network latency is low). Figure 1.3 also depicts the next batch of 50 articles (the illustration on the right) after the next link has been clicked.

If we were to click on the next link on the paginated navigation control, it would cause a full page reload, which would destroy the DOM and recreate it again. Since the comments are located at the bottom of the screen, upon a full page reload, the scroll position may also change back to the top of the web page, resulting in a poor user experience.

We only wanted to see the next set of comments at the bottom of the page. We didn't intend for the whole web page to reload, but it did, and that's the major limitation of the classic web application architecture.

Note

Wish list item #1: To enhance the user experience, clicking on a link on the website should not cause a full page reload.

 

The AJAX web application architecture


With the advent of the XMLHttpRequest (XHR) object, the Asynchronous JavaScript And XML (AJAX) era began. Figure 1.4 illustrates the AJAX web application architecture. 

After the client's initial request, the server sends back a web page response containing HTML, CSS, and JavaScript. Once the web page has finished loading, the JavaScript application on the client side may initiate asynchronous requests back to the web server over HTTP, using the XHR object.

Note

Some observers have characterized the advent of AJAX as the Web 2.0 era, where websites became more interactive with more rich user experiences and the use of JavaScript libraries started to gain traction.

Figure 1.4: The AJAX web application architecture

Because the XHR calls are asynchronous in nature, they don't block the single threaded JavaScript application running in the web browser. Once a response is received from the server for a given XHR request, an action can be taken with the data that was returned from the server.

The primary advantage

The primary advantage of the AJAX web application architecture is that it removes the need to perform a full page reload.

In the scenario that we considered with the news article web page that had 10,000+ comments, we can program the web application to initiate an XHR call when the Next button is pressed, then the server can send back an HTML fragment that contains the next set of comments to display. Once we get back the next set of comments, we can have JavaScript dynamically update the DOM, and completely avoid the need to perform a full page reload!

Figure 1.5 illustrates this approach. The left-most illustration depicts the comments in the comment section. The middle illustration depicts only the comments section being updated. Finally, the illustration on the right depicts the next batch of comments loaded in the comments section:

Figure 1.5: When the Next link is clicked, only the comments section of the news website is updated, avoiding a full page refresh

As you can see, the primary advantage of this approach is that we avoid the full page reload, which enhances the user experience. Keep in mind that in certain scenarios, such as navigating through different sections of the website, full page reloads may still occur.

Disadvantages

The AJAX web application architecture comes with the following disadvantages:

  • Handling the mental context switch between two programming languages
  • The complexity introduced by performing piecemeal client-side rendering
  • The duplication of efforts

Mental context shifts

When it comes to developer productivity, we have now introduced a mental context shift (also known as a cognitive switch) assuming that the back-end server-side language is not JavaScript. For example, let's consider that our back-end application is implemented in Go and the front-end application is implemented in JavaScript. Now, the developer will have to be fluent in both the server-side language (Go) and the client-side language (JavaScript) which apart from syntactical differences may have a different set of guiding philosophies and idioms.

This causes a mental context shift for the full stack developer that is tasked with maintaining the client side and the server side of the codebase. One way for organizations to immediately address the issue of mental context shifts is to reach into the pocketbooks. If the organization can afford to do this, it could take the hit in increased operating costs and dedicate at least one developer to the front-end and one developer to the back-end.

Note

Wish list item #2: To increase maintainability, there should be a single, unified, project codebase, which is implemented in a single programming language.

Increased rendering complexity

In addition to introducing the mental context shift of handling two different programming languages, we have now increased the level of rendering complexity. In the classic web application architecture, the rendered web page that was received from the server response was never mutated. In fact, it was wiped out once a new page request was initiated.

Now, we are re-rendering portions of the web page in a piecemeal fashion from the client side, which requires us to implement more logic to make (and keep track of) subsequent updates to the web page.

Note

Wish list item #3: To increase efficiency, there should be a mechanism to perform distributed template rendering.

Duplication of efforts

The AJAX web application architecture introduces a duplication of efforts between the server side and the client side. Let's say that we wanted to add a new comment to the news article. Once we fill out the form, to add the new comment, we can initiate an XHR call, which will send the new comment, that is to be added, to the server. The server-side web application can then persist the new comment to the database, where all comments are stored. Instead of refreshing the entire web page, we can immediately update the comment section to include the new comment that was just added.

A basic tenet in computer programming, and especially in web programming, is to never trust user input. Let's consider the scenario where the user may have introduced a set of invalid characters into the comment box. We will have to implement some type of validation that checks the user's comment, both on the client side and on the server side. This means that we'll have to implement client-side form validation in JavaScript and server-side form validation in Go.

At this point, we have introduced a duplication of efforts in two programming languages spread across two different operating environments. Besides the example we just considered, there may be other scenarios that require duplication of efforts when going down this architectural path. This happens to be a major disadvantage of the AJAX web application architecture.

Note

Wish list item #4: To increase productivity, there should be a means to share and reuse code across environments to avoid the duplication of efforts.

 

The single page application (SPA) architecture


In 2004, the World Wide Web Consortium (W3C) started working on the new HTML standard, which was to be the precursor to HTML5. In 2010, HTML5 started to pick up speed, and features from the specification started to make their way into the major web browsers and the HTML5 functionality became very popular.

The major selling point for HTML5 was to introduce capabilities that would allow web applications to behave more like native applications. A new set of APIs that were accessible through JavaScript were introduced. These APIs included the functionality to store data locally on the user's device, better control of the forward and back button (using the web browser's History API), a 2D canvas for rendering graphics, and the second version of the XHR object that included greater capabilities than its predecessor:

Figure 1.6: The Single Page Application (SPA) Architecture

In the early 2010s, JavaScript frameworks began to emerge, which facilitated in the development of a new type of architecture, the SPA architecture. This architecture, as depicted in Figure 1.6, focuses on a fat client and thin server strategy. The idea was to remove the responsibility of any type of template rendering from the server side and assign all User Interface(UI) rendering to the client side. In this architecture, there is a clear separation of concerns between the duties of the server and the client.

The SPA architecture removes the duplication of efforts for user interface responsibilities. It does so by consolidating all UI code to the client. Doing so eliminates the duplication of efforts on the server side in terms of the user interface. As depicted in Figure 1.6, the responsibility for the user interface rests solely with the client.

The server initially returns a payload containing JavaScript and client-side templates. The JavaScript payload could possibly be aggregated, which means that all JavaScript source files that comprise the web application can be combined into one JavaScript source file. In addition to that, the JavaScript payload might also be minified.

Note

Minification is the process of removing any unnecessary characters from the source code, which may include renaming identifiers in the source code without changing the functionality of the source code, in order to reduce its storage footprint.

Once the web browser has fully downloaded the JavaScript payload, the first order of business for the JavaScript code is to bootstrap the JavaScript application, rendering the user interface on the client side.

The primary advantage

The primary advantage of the SPA architecture is that it provides client-side routing, preventing full page reloads. Client-side routing involves intercepting the click event of hyperlinks on a given web page, so that they don't initiate a new HTTP request to the web server. The client-side router associates a given route with a client-side route handler that is responsible for servicing the route.

For example, let's consider an e-commerce website that has implemented client-side routing. When a user clicks on a link to the Swiss Army Knife product detail page, instead of initiating a full page reload, an XHR call is made to a REST API endpoint on the web server. The endpoint returns the profile data about the Swiss Army knife, in the JavaScript Object Notation (JSON) format, which is used by the client-side application to render the content for the Swiss Army knife product detail page.

The experience is seamless from the user's perspective, since the user will not experience the sudden white flash that is encountered on a full page reload.

Disadvantages

The SPA architecture comes with the following disadvantages:

  • The initial page loads are perceived to be slower
  • Reduced search engine discoverability

Slower initial page loads

The initial page load of an SPA-based web application can be perceived to be slow. The slowness can result from the time-consuming, initial download of the aggregated JavaScript payload.

The Transmission Control Protocol (TCP) has a slow start mechanism, where data is sent in segments. The JavaScript payload will require multiple round trips between the server and the client before it can be fully delivered to the web browser:

Figure 1.7: The initial page load is perceived to be slow since the user is greeted with a loading indicator instead of the rendered web page

A consequence of this is that users have to wait for the JavaScript payload to be completely fetched before the web page can be fully rendered. It is a common user experience (UX) practice to use a loading indicator (such as a spinning wheel) to let the user know that the user interface is still loading.

Figure 1.7 includes an illustration (on the left) that depicts the loading indicator, and an illustration (on the right) that depicts the layout of the loaded web page. It is important to note that, depending on the SPA implementation, there may be more than one loading indicator spread across the individual sections that make up the web page.

I'm sure that, in your own web browsing travels, you have probably used web applications that have contained these loading spinners. We can agree, from the user's perspective, that ideally we would rather want to see the rendered output instead of the spinning wheel.

Note

Wish list item #5: To make the best first impression, the website should readily display content to the user .

Reduced search engine discoverability

The use of the SPA architecture may reduce search engine discoverability. Because of the dynamic nature of rendering content on the client side, some SPA implementations may not produce well-formed HTML content that can be easily consumed by search engine bot crawlers that are used to consuming an initial web page response only.

The search engine bot crawler may not have the capability to render the web page, since it may not be equipped with a JavaScript runtime. Without the fully rendered web page content, the bot crawler cannot effectively perform its duty of consuming the web page's content.

In addition to this, SPA implementations handle routes using fragment identifiers, strings that refer to a resource, after the hash mark (#) of a URL. This approach is not search engine friendly.

Let's return to our e-commerce web application example. In the classic and AJAX web application architectures, our web application could have the following URL: http://igweb.kamesh.com/product-detail/swiss-army-knife.

In the case of the SPA implementation, the URL, with a fragment identifer, could look like this:http://igweb.kamesh.com/#section=product_detail&product=swiss-army-knife

This URL would be difficult for a search engine bot crawler to index because the fragment identifier (the characters after the hash symbol) is meant to specify a location within a given web page. 

Fragment identifiers were designed to provide links within sections of an individual web page. The fragment identifier influences the web browser's history since we can tack on unique identifiers to the URL. This effectively, prevents the user from encountering a full page reload.

The shortcoming of this approach is that fragment identifiers are not included in the HTTP request, so from a web server's perspective, the URL, http://igweb.kamesh.com/webapp#orange, and the URL, http://igweb.kamesh.com/webapp#apple, are pointing to the same resource: http://igweb.kamesh.com/webapp.

The search engine bot crawler would have to be implemented in a more sophisticated manner to handle the complexity of indexing websites containing fragment identifiers. Although Google has made considerable progress on this problem, implementing URLs, without the fragment identifiers, is still the recommended best practice to ensure websites are easily indexed by search engines.

It is important to note is that in some cases, the SPA architecture may overcome this disadvantage, using more modern practices. For example, more recent SPA implementations avoid fragment identifiers altogether, using the web browser's History API to have more search engine friendly URLs.

Note

Wish list item #6: To promote discoverability, the website should provide well-formed HTML content that is easily consumed by search engine bots. The website should also contain links that are easily indexed by search engine bots.

 

The isomorphic web application architecture


The isomorphic web application architecture consists of implementing two web applications, one on the server side and one on the client side, using the same programming language and reusing code across the two environments:

Figure 1.8: The Isomorphic Web Application Architecture

As depicted in Figure 1.8, business logic can be shared across environments. For example, if we had defined a Product struct to model a product for our e-commerce website, both the server-side and client-side applications can be made aware of it.

In addition to this, a template renderer exists on both the server side and the client side, so that templates can also be rendered across environments, making templates isomorphic.

Note

The term isomorphic can be used to describe anything (business logic, templates, template functions, and validation logic) that can be shared across environments.

The server-side route handler is responsible for servicing routes on the server side and the client-side route handler is responsible for servicing routes on the client side. When a user initially accesses a website implemented using isomorphic web application architecture, the server-side route handler kicks in and generates a web page response using the server-side template renderer.

Subsequent user interactions with the website are performed in the SPA mode using client-side routing. The client-side route handler is responsible for servicing a given client-side route and rendering content to the web page (the user interface) using the client-side template renderer.

The client-side application can initiate a XHR request to a Rest API endpoint on the web server, retrieve data from the server's response, and render content on the web page using the client-side template renderer.

An Isomorphic Go web application may optionally utilize a WebSocket connection, as shown in Figure 1.8, for persistent, bidirectional communication between the web server and the web browser. Isomorphic Go web applications have the added benefit of sending and receiving data in the gob format—Go's format for binary encoded data. Encoding and decoding data to the gob format can be done using the encoding/gob package from the standard library.

Note

Gob encoded data has a major advantage over JSON—it has a smaller data storage footprint.

The primary advantage of the gob format is its lower storage footprint. JSON data is in text format, and it's understood that data formatted as text requires a heavier storage footprint when compared with a binary encoded format. With smaller data payloads exchanged between the client and server, the web application can benefit with faster response times when transferring data.

Wish list fulfilled

The Isomorphic Web Application Architecture offers a solution for all of the disadvantages found in the three traditional web application architectures. Let's take stock of the items that we've placed on our wish list:

  1. To enhance the user experience, clicking a link on the website should not cause a full page reload.
  1. To increase maintainability, there should be a single, unified, project codebase that is implemented in a single programming language.
  2. To increase efficiency, there should be a mechanism to perform distributed template rendering.
  3. To increase productivity, there should be a means to share and reuse code across environments, to avoid the duplication of efforts.
  4. To make the best first impression, the website should readily display content to the user.
  5. To promote discoverability, the website should provide well-formed HTML content that is easily consumed by search engine bots. The website should also contain links that are easily indexed by search engine bots.

Now, it's time to examine how the isomorphic web application architecture fulfills each item that has been placed on our wish list.

1. Enhancing the user experience

After the initial server-side rendered web page response, the isomorphic web application architecture enhances the user experience by running in the SPA mode. Client-side routing is used for subsequent user interactions with the website, preventing full page reloads and enhancing the user experience of the website.

2. Increasing the maintainability

Maintainability of the project codebase is strengthened by the isomorphic web application architecture due to the fact that a single programming language is used to implement both the client-side and server-side web applications. This prevents the mental context shifts that occur when dealing with two different programming languages across environments.

3. Increasing the efficiency

The isomorphic web application architecture increases the efficiency of rendering content by providing a mechanism for distributed template rendering—the isomorphic template renderer. With a template renderer present on both the server side and the client side, as depicted in Figure 1.8, templates can easily be reused across environments. 

4. Increasing the productivity

The single unified codebase that is the hallmark of the isomorphic web application architecture provides many opportunities to share code across environments. For example, form validation logic can be shared across environments, allowing a web form to be validated, both on the client side and the server side using the same validation logic. It is also possible to share models and templates across the client and the server.

5. Making the best first impression

The isomorphic web application architecture's usage of server-side rendering for the initial web page response, guarantees that the user will see content immediately upon accessing the website. For the first encounter with the user, the isomorphic web application architecture takes a page out of the classic web application architecture's playbook for providing the initial web page response.

This is a welcome benefit to the user, since content is displayed to them instantly and the user will perceive a fast page load as a result of this. This is a sharp contrast to the SPA architecture, where the user would have to wait for the client-side application to bootstrap before seeing the web page's content appear on the screen.

6. Promoting discoverability

The isomorphic web application architecture promotes discoverability, since it can easily provide well-formed HTML content. Keep in mind that the rendered output of Go templates is HTML.

With an isomorphic template renderer, HTML content is easily rendered on the client side and the server side. This means that we can provide well-formed HTML content for traditional search engine bot crawlers that simply scrape web page content, as well as for modern search engine bot crawlers that may be equipped with a JavaScript runtime.

Another means by which the isomorphic web application architecture promotes discoverability is that well-formed URLs can be defined by the application's route handlers (both on the server side and client side) and these URLs can easily be indexed by search engine bot crawlers.

This is possible because the route handler implemented on the client side makes use of the web browser's History API to match the same routes that are defined on the server side. For example, the /product-detail/swiss-army-knife route for the Swiss Army Knife product detail page can be registered by both the server-side and the client-side routers.

 

Live demo


Now it's time to see the isomorphic web application architecture in action. A live demo of IGWEB, the website that we will be implementing over the course of this book, is available at http://igweb.kamesh.com. Figure 1.9 is a screenshot of the website's home page:

Figure 1.9: IGWEB: A website implemented with Isomorphic Go

Notice that the content in the above the fold area (the area that is visible in the browser window) is displayed instantly. Also, take note of the responsiveness of the website when navigating to different sections of the website by clicking on the links in the navigation menu. We'll provide you with a detailed introduction to the IGWEB project in the next chapter.

Note

At the time of writing, IGWEB has been verified to function in the following web browsers: Google Chrome version 62.0, Apple Safari version 9.1.1, Mozilla Firefox 57.0, and Microsoft Edge 15.0. It is recommended that you use a web browser that has the same version, or above the version, provided in this list.

 

Measurable benefits


The methodology to develop an isomorphic web application using Go, that is presented in this book, has proven, measurable benefits with regard to providing an enhanced user experience.

We can use the Google PageSpeed Insights tool (https://developers.google.com/speed/pagespeed/insights/) to evaluate the performance of IGWEB's home page. The tool measures how well a web page delivers a good user experience, on a scale of 0 to 100, based on various criteria, namely the organization of web page content, size of static assets, and time taken to render the web page:

Figure 1.10: The result of running the IGWEB home page through the Google PageSpeed Insights tool

Figure 1.10 is a screenshot that shows the result of evaluating the desktop edition of IGWEB. At the time of writing, IGWEB scores 97/100 for the desktop browsing experience, and 91/100 for the mobile browsing experience. According to the tool, the 90+ score attained for both the desktop and mobile editions indicates that the IGWEB home page applies most performance best practices and should deliver a good user experience.

 

Nomenclature


I used the term Isomorphic Go as the title for my introductory presentation on the subject of developing isomorphic web applications in Go at GopherCon India. The title of my presentation was inspired by the term Isomorphic JavaScript. The term Isomorphic JavaScript was coined by Charlie Robbins in his 2011 blog post (https://blog.nodejitsu.com/scaling-isomorphic-javascript-code/), Scaling Isomorphic JavaScript Code.

Note

The word isomorphism comes from mathematics. In Greek, iso means equal and morphosis means to form or to shape.

A debate has existed within the JavaScript community on the usage of the term isomorphic to describe a web application that contains code that can run on either the client or on the server. Some members of the JavaScript community prefer using the term universal instead.

In my opinion, the term isomorphic is more appropriate, while the term universal introduces ambiguity. The ambiguity stems from the fact that the term universal carries some baggage along with it.

Apple has widely used the term universal binary to describe fat binaries that contain machine code for multiple processor architectures. Modern JavaScript code gets compiled into machine code by a just-in-time compiler.

Therefore, using the term universal is ambiguous, and requires extra detail, to determine the context in which it is used. For this reason, the preferred term that will be used in this book is isomorphic.

 

Prerequisites


This book focuses on teaching you how to create an isomorphic web application using the Go programming language. Since we will be taking an idiomatic approach that focuses exclusively on Go, it is not necessary to have prior familiarity with libraries and tools from the JavaScript ecosystem.

We assume that the reader has some level of prior programming experience in Go, or some other server-side programming language.

If you have never programmed in Go, I would recommend that you refer to A Tour of Go available at: https://tour.golang.org.

For a more in-depth study of fundamental Go concepts, I would recommend that you take my video course, Go Essentials For Full Stack Web Development,Packt Publishing, available at https://www.packtpub.com/web-development/go-essentials-full-stack-web-development-video.

 

Summary


In this chapter, we provided an introduction to Isomorphic Go. We covered the many advantages that the Go programming language provides, and why it makes a compelling choice for the creation of isomorphic web applications.

We reviewed the traditional web application architectures, which included the classic web application architecture, the AJAX application architecture, and the SPA architecture. We identified the advantages and disadvantages of each traditional architecture. We introduced the isomorphic web application architecture and presented how it solved all the shortcomings of the traditional architectures.

We presented a live demo of IGWEB, an Isomorphic Go website, and introduced you to the Google PageSpeed Insight tool to measure web page performance. Finally, we provided you with some background on the term isomorphic and the items that you need to know to make the most out of understanding the material covered in this book.

In Chapter 2The Isomorphic Go Toolchain, we will introduce you to the key technologies used to develop Isomorphic Go web applications. We will also introduce you to IGWEB, the Isomorphic Go website, that we will be building over the course of this book.

About the Author

  • Kamesh Balasubramanian

    Kamesh Balasubramanian is the Founder and CEO of Wirecog, LLC. He is the inventor of Wireframe Cognition (Wirecog), an award-winning, patented technology that allows machines to understand wireframe designs and produce source code from them. Kamesh has over 20 years of software development experience and has implemented numerous solutions in the advertising, entertainment, media, publishing, hospitality, video game, legal, and government sectors. He is an award-winning, professional member of the Association for Computing Machinery and an InfyMaker Award winner. He was recognized as a “Maker of Change” at the 2016 World Maker Faire in New York and, upon request, has demonstrated Wirecog at MIT.

    Browse publications by this author

Latest Reviews

(3 reviews total)
The writer was promoting his Isomorphic Go, which was not hosted in github any more, no other contributors. I was regret not discovered before buying the book.
Easy, quick and Paypal-enabled
Poor. Content is ok, but let down by grammar and formatting.

Recommended For You

Book Title
Access this book and the full library for FREE
Access now