AJAX Head Design Pattern
Ken Collins from MetaSkills originally posted on his blog about the concept of an Ajax Head pattern in which he describes a pattern for providing a thin controller API that is responsible for initial GET response and all other actions beyond that are Boolean responses. He sums up the entire pattern, from his perspective, in a single quote:
The AJAX head design pattern forces the view and controller to work in isolation with the most minimal coupling possible. Kind of like a web service.
I have been working on several projects that are utilizing a variant, or as I would contend the resultant of this pattern, in very interesting and rewarding ways. I wanted to provide a more robust and implementation agnostic definition to the pattern, because I believe this pattern is quite revolutionary in the world of web programming. It serves well to resolve many of the issues that plague web application development since it focuses on isolation, encapsulation, and delegation of responsibilities. I have chosen to describe this pattern, as I view it, using the model set forth by the Patterns of Enterprise Application Architecture by Martin Fowler. I encourage you to read through the pattern and suspend or at least delay your immediate reaction until after you try using the pattern. In all cases that I have used it, it has felt more natural, more dynamic, and surprisingly faster than the competitive pattern of embedding dynamic data into static templates at run time. Enjoy.
AJAX Head
Web Applications, like many enterprise applications, are composed of several layers of data processing in order to properly and meaningfully decompose the problem set into encapsulated components.These components are constructed in a fashion that they can be used by any layer above them without knowing the details of layers below them. This creates a contract between the consuming layer and the providing layer regarding the expectation details and not the implementation details. In web applications, the concept of layering commonly stops being applied after the Service Layer [Staffor, PEAA] and utilizes a mixture of embedded behavior, data, and structure that is rendered out to a specific interface format.
The AJAX Head pattern provides a thoughtful approach of how to maintain separation of behavior, data, and structure by extending the concept of layering into the user interface component. Furthermore, the AJAX Head pattern describes an implementation pattern that drastically modifies common web client-server interactions in order to bring them more closely in line with enterprise client-server interactions. This pattern relies heavily on the separation and isolation of responsibilities between components which yields better encapsulation and testability of each component.
How It Works
The AJAX Head Design Pattern can be implemented with any combination of server programming languages and client side languages, but does require that an Asynchronous JavaScript And XML connection can be established between the two endpoints (client->server). The basis of the pattern rests on the following key components:
- Statically defined HTML files that include single instance “templates” with sample data for all areas of the user interface that are meant to be dynamic. These HTML files should be descriptive of their intention through the use of proper and meaningful tags, identification, and classing derived from the specific domain. This layer is responsible for describing the structure and indicating the intention of the requestor. It provides “templates” for how the fulfillment of those intentions should be represented in order to be meaningful.
- Statically defined JavaScript files that include behavior definitions of the HTML pages as well as the ability to query and parse the data feeds provided by the server. This layer is responsible for detecting the requested intention, describing the intention to the Service Layer, and applying the response to the defined structure.
- A server side application programming interface (API) that can handle web service requests (XML-RPC, REST, SOAP, etc.) and produce standardized data responses appropriate for the request. The responses need to be in a format that is uniform across the API and retains the structure and composition of the data. Recommendations for this include JavaScript Object Notation (JSON), XML, or CSV. This layer is commonly referred to as the aforementioned Service Layer and is responsible for appropriate calling sub layers and performing any necessary processing in order to fulfill the intention.
With these components the following workflow defines the process of rendering a single page:
- The browser requests a web page.
- The server returns the static HTML page appropriate to the request.
- The browser parses the HTML page and requests the necessary and appropriate JavaScript behavior definitions described by the HTML page.
- Once interpreted by the browser, the JavaScript behaviors will query the server using AJAX for the appropriate data elements. These AJAX requests will be fulfilled with the defined data format based on the request.
- The behavior definitions will parse the data feed and render the elements into the HTML structure based on the provided single item templates. If there are no items, the template is removed.
- Interaction and behavior updates are applied to the new data elements as described in the behavior definitions.
Differences From Other Patterns This differs tremendously from the embedded template pattern currently employed in most web application frameworks because it pushes all of the rendering down to the client system, distributing the load and strain on the server across the interacting components. This pattern leverages the prevalence and availability of network connectivity with the server to reverse the presentation work flow from render and serve to serve and render. This key difference allows for a natural separation and encapsulation between the components of the presentation system. It normalizes the user interface into an interaction interface through a standard API, thus enforcing and encouraging web service style development with true abstraction between the layers.
Results A result of this separation is that all of the presentation components can be thoroughly tested in isolation and with automation. This is important because it not only facilitates isolated testing, but specifica and appropriate creation as well. It allows developers to develop the functional code, designers to design and construct the front end user interface components, and a intermediary programmer/designer to wire the two layers together without affecting or influencing the creation of either. Since this design pattern abstracts the structure, behavior, and functional components from one another without a blending of components as occurs with embedded templates, the removal, replacement, or modification of one component does not adversely or greatly affect the others. If a backend is replaced with a different backend, it does not require a new user interface to be rewritten. If a new JavaScript libraries is chosen or replaced with a competitive technology (Flash, SilverLight, etc.) it does not require a modification of any other element. Finally, the changes in the HTML structure only need to be known and, if necessary, handled by the layer that interacts with it directly, so replacing it is as easy as the other two.
Implementation Variations As identified in the Ken Collins article, there is one variation of this pattern that requires the service layer to respond to requests with either an error explanation or a success, which in his case was a “200 OK” HTTP response. Another, more verbose implementation variation leaves the response content open to the API definition, since there are possible actions or calls that might change the state or attributes of an object beyond the appropriate knowledge of a behavior/requestor. The latter of these variations is recommended by the author.
Advanced Implementation Details Advanced details of this pattern can be applied iteratively over time and need not be implemented or provided all at once. These details are not necessary for all implementations, but are provided here for use in certain cases.
- The AJAX requests can be sent over multiple sub-domain names providing multiplexed requests for data. This provides substantial improvements in performance since the requests will be parallelized in the request, response, and rendering process.
- Since all initiating components of the interaction sequence are statically defined and hold no sensitive data, they can be delivered not just by the server, but through a Content Distribution Network (CDN) for fast, highly distributed, and localized provision of the components.
When to Use It
This design pattern can be used for any web application, even those requiring authentication or privileged access because the static HTML pages, which are publicly available, provide no “domain specific” data, only structure and style. All access is controlled and negotiated between the behavior and the controller layers. This pattern works sufficiently well for nearly all web applications and in most circumstances can replace all embedded templates in an application. It can also be intermingled with embedded templates since the pattern does not require complete and holistic application in order to obtain the benefits.
Further Reading
There is little prior art for this design pattern, though many JavaScript libraries have begun to head in this direction. I recommend reviewing the following libraries/frameworks that assist with the implementation of this design pattern:
- BeeBole Pure - a Fast JavaScript Rendering Library.
- Chain.js - a jQuery library for data binding the elements of a feed to HTML.
- Dissident - a framework based in Erlang built from the ground up around the AJAX Head design pattern, this is still under construction by the author.