AJAX and Web 2.0

Many web applications need to communicate with a server to fetch and store information. An early mechanism for storing information on servers was to use the HTML form element.

A more modern approach for interacting with a server is to use the JavaScript programming technique known as AJAX (Asynchronous JavaScript and XML). Here are the key aspects of the AJAX style of programming:

  1. A page developer uses JavaScript to implement interactivity by providing event handler functions linked to buttons or other page elements.
  2. When a user clicks a button, the JavaScript event handler function for that button sends a request for data to a web server.
  3. The web server responds not with an HTML page, but with data encoded in a form that is easy for JavaScript to process.
  4. The JavaScript in the page receives the data and integrates the data back into the page using DOM manipulation techniques.

The data that comes from the server can be the result of some complex computational process. The work of managing that process is left to the software developers who write the software for the server. The JavaScript developer is left with the relatively simple task of formulating the request and then integrating the result data back into the page. This arrangement is superior to the form processing paradigm, because in this arrangement each developer can concentrate on their particular areas of expertise: server developers only worry about data, while the page developer concentrates on presentation via HTML and CSS and page manipulation via DOM techniques.

The style of interactivity described above lead to a minor revolution in web development. Some of the early pioneers of this style of development, including the team that designed the web interface for GMail, were able to use these techniques to introduce an entirely new class of web applications. These new applications were a sufficiently radical departure from earlier form-based interactivity that developers attached the term "Web 2.0" to applications built using this new style of development.

JSON

When AJAX was first developed, the encoding system used to transfer data from the server to the page was XML, which is a data description language created by the World Wide Web Consortium, or W3C. (The W3C is headed up by Tim Berners-Lee, the inventor of the World Wide Web.) Getting JavaScript to play well with XML data is something of a challenge, so over time JavaScript developers went looking for an alternative scheme for encoding data. The scheme that eventually emerged as a clear favorite for AJAX development was the JavaScript Object Notation, or JSON. JSON encodes JavaScript data in the form of a text string whose structure closely mirrors the structure that JavaScript itself uses to represent data via arrays, objects, and simple data types such as numbers and text.

Here is an example of some JSON encoded data:

[{"cost":795,"iditem":8,"meal":"dinner","name":"Spaghetti Dinner"},{"cost":895,"iditem":9,"meal":"dinner","name":"Fried Chicken"},{"cost":895,"iditem":10,"meal":"dinner","name":"Stir Fry"}]

The example encodes an array containing three objects. The only difference you will see here between JSON notation and JavaScript notation is that in JSON notation all of the property names for object literals have to be enclosed in quotes.

Since JSON is so close in form to JavaScript, converting a chunk of JSON text into JavaScript data is relatively simple. In all of the examples I will be showing in this class we will use JQuery functions to do AJAX operations for us. Those functions will take care of converting our JavaScript data to and from JSON form for us automatically.

REST

One final piece of the puzzle needed to implement AJAX is a server that can deliver JSON data to us. Another technology needed to implement such a server is REST, which stands for Representational State Transfer. REST is a server architecture standard, and server developers build server applications to conform to the key aspects of the REST style.

The foundation of REST is the language that web browsers and web servers use to communicate with each other, the Hypertext Transfer Protocol, or HTTP. When a browser sends a request to a web server via HTTP the browser will ask for data via a combination of an HTTP verb (which specifies what we want to do with the data) and a URL (which identifies the data we want to act on). In the vast majority of cases browsers want to fetch a page: for that kind of interation the browser will send the GET verb followed by a URL that identifies the page the browser wants delivered.

When Tim Berners-Lee developed HTTP he envisioned something a little more complex than a system for just fetching web pages. In his original vision for the web, he imagined a system in which users could fetch web pages, edit them in a browser, and upload their edits back to a web server. To facilitate this, he provided HTTP with four different verbs.

VerbWhat it does
GETFetches data (usually a web page)
POSTUploads data to the server
PUTUpdates data on the server
DELETERemoves data from the server

In addition to accomodating a range of data operations, HTTP also offers standardized ways to transfer data. For example, when a browser sends a GET command to a server, it knows to expect data in the response. Specifically, when the response comes back it will have a body, and the requested data will appear in that body. Likewise, a POST command going to a server can have a body, and that body can contain data that we want to upload to the server.

The upshot of all of this is that HTTP was built right from the very start as a system for managing the flow of data back and forth between browsers and servers. Most of these capabilities stayed dormant for many years and were not used. Eventually, though, someone figured out how to leverage the full power of HTTP to make a data architecture based on the web and HTTP. That architecture is called REST, and it uses HTTP (verbs and URLs) along with a data representation (XML or JSON) to make a complete computing infrastructure. REST is another key element of the Web 2.0 style of programming, in that AJAX is most often used with REST based servers that offer what are known as RESTful web services.

Working with a RESTful web service

To begin to explain how REST web services work, I have set up a simple web service at cmsc106.net. This web service serves up data on menu items and orders at an imaginary cafe. This will allow us to complete the cafe ordering application from last week by fetching menu items from the server and uploading orders to it.

Interaction with a web service starts with URLs. Web services typically offer access to several related pools of data, and the data collection we want to access gets built into the URL. For example, to access information about available menu items we will be using a URL like this:

http://cmsc106.net/cafe/item

This URL consists of several components. The first component is the server we want to contact, cmsc106.net. The next part of the URL, /Cafe, identifies the web application we want to interact with. Since a single server can host multiple applications, we have to identify a specific application to interact with. Since we want to access the web services portion of the cafe application, we have to attach /api to the URL. Finally, since a web service typically offers access to many different data collections, we have to identify the data collection through the /item part of the URL.

Once we have a properly constructed URL the web service will respond by serving up some data. In this case, the web service will respond with

[{"meal":"breakfast","iditem":1,"cost":495,"name":"Breakfast Burrito"},
{"meal":"breakfast","iditem":2,"cost":395,"name":"Oatmeal"},
{"meal":"breakfast","iditem":3,"cost":595,"name":"Two Egg Combo"},
{"meal":"lunch","iditem":4,"cost":595,"name":"Grilled Panini"},
{"meal":"lunch","iditem":5,"cost":495,"name":"Soup of the Day"},
{"meal":"lunch","iditem":6,"cost":495,"name":"Hamburger"},
{"meal":"lunch","iditem":7,"cost":495,"name":"Felafel Sandwich"},
{"meal":"dinner","iditem":8,"cost":795,"name":"Spaghetti Dinner"},
{"meal":"dinner","iditem":9,"cost":895,"name":"Fried Chicken"},
{"meal":"dinner","iditem":10,"cost":895,"name":"Stir Fry"}]

This is a JSON encoded list of menu items.

Since browsers implement GET requests any time you type a URL into their address bar, you can put the URL above into Google Chrome to see the data that the server responds with.

Sending a GET request to a web service from JavaScript

Since we are going to be using a web service as a data source, we next need to cover how to contact the web service from a JavaScript program. We will be using the JQuery $.getJSON() function to do this.

The sample code below demonstrates how $.getJSON() works in the cafe application.

// Callback function for the fetch items query
function receiveItems(data) {
  items = data;
  $('div#starting').hide();
  $('div#view').show();
  displayMeal('lunch');
}

$.getJSON('http://cmsc106.net/cafe/item',receiveItems);

One new aspect of getJSON as a function is that it will process the GET request asynchronously. Calling getJSON sends our request to the server at the indicated URL, but does not return any information. When the response eventually comes back from the server, JQuery will react by calling a special callback function specified in the second parameter to getJSON. The callback function for this example, receiveItems, has a single parameter, data. When JQuery calls our callback function it will pass any data that came back from the server to the callback function in that data parameter. receiveItems will take that data and assign it to the global variable items so it can be available to other parts of the application. Once the initial data for the application has arrived from the server we can hide the div that displays the 'starting up' message, show the div where the menu items get displayed, and then call the displayMeal function to fill the menu table with items.

POSTing data to the web service

At the other end of the application we will want to upload orders to the server. To do this we will POST our data to the URL http://cmsc106.net/Cafe/api/purchase. The purchase collection contains information about orders and expects us to upload objects that have the following form:

{customer:"Joe",phone:"555-1212",items:[6,7]}

The following code shows how to do this:

// Event handler for the place order button
function placeOrder() {
  // Construct a list of id numbers for the ordered items
  var n, length, ids;
  ids = [];
  length = order.length;
  for(n = 0;n < length;n++)
    ids.push(order[n].iditem);
  // Construct the order object
  var toPost = {customer:$('input#name').val(),
                phone:$('input#phone').val(),items:ids};
  // POST it to the server
  $.postJSON('http://cmsc106.net/cafe/purchase',
              toPost,showConfirm);
}

The second parameter to $.postJSON is the object we want to send to the server. You will see that object being assembled in the statements right before the call to $.postJSON.

As in $.getJSON, the last parameter to $.postJSON is the name of a callback function. JQuery will call this function when it receives confirmation from the server that the POST was successful. The server we are working with will respond to a successful POST to purchase by returning an order number. In this application we will use the following function as a callback for $.postJSON:

// Success callback for the place order POST
function showConfirm(data) {
  $('span#number').text(data);
  $('div#order').slideUp();
  $('div#confirm').show();
}

This function places the order number in the page, hides the ordering div and shows a confirmation div where the user will see a confirmation message.

One final comment about $.postJSON - this function is actually not part of the JQuery library. Instead, I was forced to write my own version of this function and patch that function into JQuery. My code for $.postJSON makes use of a lower level function $.ajax that JQuery provides to give more fine-grained control over AJAX queries.

// Work-around for missing JQuery.postJSON
jQuery["postJSON"] = function(url,data,callback) {
  $.ajax({
    url:url,
    type:'POST',
    data:JSON.stringify(data),
    contentType:'application/json',
    dataType:'json',
    success: callback
  });
};

You can copy and paste this code into any project to implement $.postJSON.