MVVM with no data binding: Libraries such as jQuery and d3.js provide a wrapper over DOM manipulation, but they do not offer guidance for structuring single-page web apps. The classic model-view-controller (MVC) pattern was brought over to the web with revised terminology: model-view-view model (MVVM). A view model distinguishes that it exists in a web browser rather on a server. Backbone.js first introduced a popular MVVM to front-end web apps. Backbone.js offers a simple view model and synchronization to a web server’s REST API. On the other hand, Backbone.js offers no guidance in manipulating the DOM other than to use jQuery.
MVVM with two-way data binding: MVVM frameworks such as Backbone still require jQuery to manipulate the DOM. Two-way data binding was introduced to synchronize the view model with the DOM. Two popular frameworks for two-way data binding are Angular.js and Ember.js. Both are used in production for single-page web apps. As I see it presently, these are the state of the art technologies that every developer should know.
In summary, I’ve categorized 5 major approaches for building single-page web apps. Each approach attempts to solve unnecessary engineering effort and complexity of a previous approach. If you have something new to share, please write to me and I’ll include it in another blog post.
Let’s step back a century for a minute. When the United States was first getting wired with the telephone network, people called into switchboards located within each city. The switchboard operator (a person) would talk to the caller to route the line to the destination. As the system grew larger, switch numbers were offered to help operators find the connecting line faster. Electronic switching replaced switchboard operators and expanded the length of telephone numbers to their current 10 digits. The first 3 digits represents the area. The second 3 digits represents the regional switchboard. The last 4 digits is the person’s number.
In addition to representing local telephone numbers, special area numbers were introduced for specific purposes, for example, 800 for toll-free calls. These special numbers were bought by businesses to represent their national presence. The choice of telephone number was, and still is, very important for both residential customers and companies today.
URLs: The Telephone Number of the Internet
The first generation Internet was launched in the early 1990s. Hypertext documents on the Internet each had their own unique URL. If someone wanted to reopen the document, the person would navigate back to the same URL. The URL connects the reader to the document in the same way a the telephone number connects an individual’s call.
Websites with personalized content (the 2nd generation Internet) started appearing soon after. These websites required state to be maintained between page reloads, for instance, to maintain a login session. Although some early URLs added hashes to save state, state is often saved in the web browser using a cookie in the request-response cycle. A URL, thus, cannot retrieve the exact state of a website.
Front-End Web Applications
In the early 2000s websites started having more interactive content. Instead of reloading a web page for this content, front-end web applications were introduced to run inside the web browser. The website would download a Flash plugin, Java applet, or something similar. Site-specific code would then run inside the plugin for the web application. URLs didn’t reflect the state of these web applications because plugins weren’t allowed to rewrite URLs (because of a security sandbox).
URLs for Front-End Web Applications
The open challenge is to design these URLs to expose the appropriate state for front-end web applications. Tom Dale suggests the URL has three components, which mirror the MVC (model-view-controller) design of Angular and Ember. I’m currently researching other state representations in URLs.
The URL is the gateway to a web application. In years past, we were unable to represent a web application’s state in the URL because of technical limitations. Today, modern front-end web applications can represent a state. It is now up to web developers to design URLs with the same care and attention that telephone numbers received in the last century.
Node.js is a lightweight platform for building a server application, which offers an event-driven framework for handling socket input and output. This is really useful for customizing Node.js to solve a specific problem, and it makes Node.js very fast. In most cases, though, we are building applications that are similar to one another, such as a web application. Rather than reinventing the wheel each time, we take advantage of open-source frameworks that help build a web application on Node.js.
When building a web application framework, a web browser makes HTTP requests to a web server and the web responses back with content. The Express.js framework encapsulates this behaviour in Node.js so a developer doesn’t have to handle sockets directly. For serving HTML content to a web browser, the Jade template library provides an abstraction from writing HTML. Over time many reusable components in a web application are needed, such as a database connection or authentication library. The Architect framework provides a convenient structure for including such libraries into a Node.js application.
Those familiar with building a Ruby on Rails or Python Django web application will immediately notice that we already have web frameworks and reusable open-source libraries. The programming language in which they were written, however, are silos that prevent library reuse. So we reinvent the wheel for each programming language.
The trend in Node.js is a reinvention of the pieces that eventually result in a heavyweight framework. Heavyweight frameworks provide all the features you need out of the box at the expense of additional computation overhead. The computation overhead, however, is an acceptable tradeoff because a developer’s time is more valuable spent in writing custom business logic. The ecosystem of libraries in Ruby on Rails and Python Django offer many reusable libraries, which reduces development time. I believe the same trend is happening in the Node.js community and that a heavyweight framework will emerge.