Skip to content

Html bundles

danieldkim edited this page Apr 21, 2012 · 2 revisions
Clone this wiki locally

HTML Bundles

The html bundle media type is a format that is designed to be an optimization of HTML. As such, it provides the same hypertext processing model as HTML but addresses several design goals:

  • reduced network overhead for download of HTML resources

  • programmatic access to the core data of a resource (REST APIs)

  • for AJAX applications, the ability to "load" an HTML page without invoking a true web browser page load

  • client-side reuse of the template source code used for server-based HTML generation

The html bundle type is designed to allow client applications to access resources with a HTML-browser-like processing model but to do so in a more network-efficient manner. It leverages the inherently RESTful characteristics of the HTML media type to enable automatic derivation of, from typical server implementations of HTML resources, APIs that are also RESTful in the Fielding-ian sense.

The Format

It has become common practice in web server programming environments to separate the core data that define resources -- otherwise known as models -- from elements of their presentation in HTML format -- otherwise known as views. Though this distinction is transparent to the browser client it is pervasive in servers -- practically ubiquitous in dynamic web application server environments.

An html bundle is an alternative to the full HTML representation of a resource that can be used by clients that can process the bundle. It contains all the information necessary to generate the full HTML representation:

  • the model component(s) of the resource, in serialized form.

  • the view source code for the resource, often referred to as templates.

  • other metadata, i.e. the version of the resource.

Specifically, an HTML bundle will have:

  • a template attribute which contains either the view source code inline or a URL that points to the template file.

  • a locals attribute which contains the model data that will be available as local variables to the view template

  • other optional implementation-specific attributes

The information in an html bundle can be represented in any suitable text-based structured data format, i.e. json or xml. For instance, this is what an HTML bundle in JSON might look like:

{
    "template": "home/index",
    "locals": {
        "currentUser": {
            "_id": "4eb5f5dc480534b4f784d40f",
            "firstName": "John",
            "lastName": "Doe"
        },
        "title": "Home",
        "posts": [{
            "_id": "4f694d16adb91de605000001",
            "createdAt": "2012-03-21T03:37:58.359Z",
            "title": "Even eggs can be catty...."
        },
        {
            "_id": "4f679f82a1f6e29f05000001",
            "createdAt": "2012-03-19T21:05:06.551Z",
            "title": "Everywhere I go there is wet paint."
        }]
    },
    "version": "1.0"
}

The format of the templates themselves is implementation specific. Templates intended to be executed in web browsers will typically be JavaScript-based. A filename extension on the template URL can be omitted if a default one is implied.

A server could choose to render templates inline in certain situations though, generally, it will be more efficient to use a URL. Here's what the bundle above with template text inline might look like:

{
    "template": {
        "type": "text/jade",
        "text": "!!! 5
                 html(xmlns='http://www.w3.org/1999/xhtml')
                   head
                     title= title
                   body
                     ul
                       - each post in posts
                         li
                           a(href='/posts/' + post._id)= post.title"
    },
    "locals": {
        "currentUser": {
            "_id": "4eb5f5dc480534b4f784d40f",
            "firstName": "John",
            "lastName": "Doe"
        },
        "title": "Home",
        "posts": [{
            "_id": "4f694d16adb91de605000001",
            "createdAt": "2012-03-21T03:37:58.359Z",
            "title": "Even eggs can be catty...."
        },
        {
            "_id": "4f679f82a1f6e29f05000001",
            "createdAt": "2012-03-19T21:05:06.551Z",
            "title": "Everywhere I go there is wet paint."
        }]
    },
    "version": "1.0"
}

Reduced Network Overhead

Html bundles exploit 2 relevant properties of views to achieve reduced network overhead:

  • their content represents a distillation of information that is redundant across an entire set of HTML representations

  • their content remains relatively static over time

These properties are already exploited on the server side for compression and reduced data storage requirements (though this is not a primary motivation for the division between model and view there). This also reduces the bandwidth requirements for downloading an HTML page (as well as local cache storage requirements) as redundant view data can be downloaded once, retained and cached until invalidated, and reused across a large set of resources. The iterative processing capabilities of many template technologies also allows redundant boilerplate code to be specified once but applied across a number of data items in models. The binding of model to view to produce the full HTML markup can be viewed as kind of decompression of a compressed representation containing the essential information in a HTML page.

Techniques for caching what are typically referred to as the "static assets" for a web page are well understood and widely practiced. Html bundles essentially allow us to extend the set of things classified as static assets to include the redundant text in HTML resources.

In the most optimized case where all static assets, including view templates, are fingerprinted and cached, it takes but one network request with a relatively small payload of dynamic model data to render a full HTML page.

This is, in essence, what AJAX with so-called data services accomplishes, though in many cases what is essentially the view template is defined in the imperative logic of JavaScript code written by application developers to process the data and translate it into DOM structures in an ad-hoc fashion. Some AJAX frameworks provide a client-side template framework to make this less arbitrary.

The difference between html bundles and a data services + templates approach is subtle but important. Html bundles are self-describing in terms of what template should be applied to the data and they map 1-to-1 with HTML web pages. This allows for a generic implementation of binding data to view to produce HTML that is consistent across all resources across all sites that follow the standard and requires no external knowledge of how data map to templates.

APIs

As mentioned above, use of html bundles offers similar benefits to AJAX in terms of reduced network overhead. They both achieve this by leveraging a similar strategy of dividing HTML representations into pure data and pure view logic components. But html bundles have advantages over typical AJAX approaches in terms of defining a standard way of mapping data to view logic that allows for a generic implementation of rendering that can be reused across all resources.

While the separation of data and view are common to both html bundles and AJAX, another advantage of html bundles is that the creation of a data API is just a coincidental side effect of html bundle implementation. The 1-to-1 mapping between html bundles and their associated web pages also allows for reuse by the REST API of the interface and processing model inherent in the hypertext state machine comprised by the HTML pages in a site. Such an API could be automatically derived or generated from a MVC web application that adheres to certain architectural constraints. Such constraints would include things like:

  • the models accessed by views are essentially pure data and entirely local and make no remote calls to external services

  • view source code contain no private information

An MVC web application that exhibited such architectural properties would have the boundary between its model, view, and controller layers clearly delineated. Resource controllers would already be essentially outputting something that looks like an html bundle to be processed by the application server framework. For such applications it would be straightforward to automatically derive an html bundle based REST API from the existing implementation.

This API would be to some degree self-documenting. The general conceptual model for the API would be inherent in the site and its state space could be known by simply crawling the site (either manually or with a generic crawler program). Though an API consumer might not download and execute the templates, the developer of the API-consuming application could read them to determine the logic for converting the data into the URIs for valid state transitions.

Transparent Page Loading

For many AJAX applications executing in a web browser environment it is desirable, either to enhance user experience or because of architectural constraints, to be able to load an HTML resource without invoking a browser page load. Transparent page loading (or page chunk loading, oftentimes) is, in fact, the prototypical use case for AJAX.

Web servers that provide html bundle representations of their web pages allow JavaScript code executing in web browsers to request the bundle for a page and render it without going through the browser's load function. The mechanics of this involve simply issuing a XHR GET request to the URL of the page in question with the html bundle mime type as the Accept header value and then binding the returned model to the view.

The Charlotte mobile app development framework addresses a scenario where the ability to programmatically load web pages is both desirable and mandatory. Users of native apps have generally come to expect some sort of smooth animated transition between screens and app developers want control over that transition experience. Furthermore, the PhoneGap framework that it is based on requires that the application be built as a so-called "single-page application". Charlotte provides a browser abstraction in JavaScript that can be used to build a mobile web application that is architecturally a RESTful multi-page application to run in PhoneGap. It provides on top of a low-level single-page application architecture a multi-page architecture at a higher level of abstraction.

Code Reuse

Many web applications that take advantage of html bundles to provide AJAX-style network-efficient transparent page loading and REST APIs to clients that are capable of processing them will still want to generate the full HTML representation on the server for clients that are not. Maintaining two sets of view templates, one for server-based HTML generation and one for client-based html bundle processing, is onerous, though. Ideally, one set of templates could be used for both.

Web applications built with JavaScript-based web application server frameworks, whose primary target html bundle environment is JavaScript-enabled web browsers, have an opportunity to reuse template source code in both the server and client execution environment.

It is not quite enough, however, to have a common language runtime on both the client and server. The general template processing model (i.e., how are things like partials and helper methods supported?) and the API available to template source code within that model (i.e. exactly what are the "helper methods" that are available to template source?), must be consistent in both environments. Html bundle implementations, which we'll refer to as engines, will have to provide an abstraction that makes it largely transparent to the template which environment it is running in. The engine will need to define a core template API available everywhere as part of the engine as well as a means of loading in application-specific template APIs in both the server and client environments. See Charlotte for an example of an html bundle engine that provides a common template processing environment and API for both the web server and the browser.

Html bundles + server-side JavaScript application servers afford an unprecedented opportunity for leverage and reuse, of architecture and code, for web applications that wish to offer rich, responsive user interfaces and programmable APIs, within an overall RESTful web application architecture, for their consumers. See the charlotte demo application for an example of how the code and architecture of a web application built with a standard web application architecture can be reused in an html bundle execution environment within a native iOS application.

The Mime Type

The mime type proposed for the html bundle media type is application/x-html-bundle+{engine}, where {engine} is the particular html bundle engine that is supported by the client or server. Since each engine will implement key mechanisms such as the template processing model and core template APIs differently, an engine identifier is required in the mime type to ensure that the client will have the ability to interpret the bundle.

For, example the client component of the Charlotte html bundle implementation sends application/x-html-bundle+charlotte as the Accept header value for html bundle requests. Charlotte-compatible server implementations, including Charlotte itself, can look for this header value to know when it can deliver a html bundle response that can be understood by the client.

It is hoped that over time standard template processing models, core template APIs, and application template API loading mechanisms will emerge that can be implemented by any number of engines and the +{engine} component of such mime types can be replaced by standard names.

Something went wrong with that request. Please try again.