Back to home

restful ajax web app basics ( mimic gmail with backbone.js )

The goal is to build a small example of Service Oriented Architecture (SOA) and Thin Server Architecture (TSA). We want our server to only produce raw data and never send HTML! ( We’re using REST not SOAP, no fighting).

This is a quick guide to get you started on building a one page web app that uses hashtag events and history to allow users to navigate your site without reloading the page ever. Don’t want to be circle jerking too hard but todays tutorial will be using Backbone.js again.

Demo
Source

Benefits of Thin Server Architecture

Before I continue with the tutorial here are just a few pros I can think of for using a fully ajax app with a restful interface.

  • Less HTTP request
  • Minimize the size of requested pages by always requesting JSON
  • Lets you build ajax interfaces which are fast and responsive
  • Request are already JSON so if you ever need to build an API, it’s straight forward
  • Google invented #! aka the hashbang for SE
  • !flash

I was excited the first time I wrote a fully ajax app and I hope that some of you can feel the orgasmic feeling of dynamically loaded content. With the advent of the google hashbang, you should be able to also build your websites/blogs with pure ajax calls now while still still reaping the benefits of google rankings.

Possibly one of the funnest parts is choosing an ajax loading graphic, I always use this site.

Understanding the hash tag

Backbone.js implements two classes called Controller and History. Using just these two classes we can constructthe entire backbone of our restful app.

To make a fully ajax website we need to use the hashtag, which up until this point has been used predominatly for anchor tags. Browsers don’t trigger any page refreshes with hashtags so using Javascript we can detect when the # location changes. Instead of triggering the default behavior of finding an anchor, we instead load custom Javascript.

Below is all the HTML we will be using today. Also note the inclusion of underscore.js, its a depdendecy of backbone.js and brings alot of power to the table. I have simply set up four links that shall react accordingly and hopefully load data into our content pane div.

<!DOCTYPE html>
<html>
<head>
	<title>Hide your kids, hide your wife and hide your husbands</title>
</head>
<body>

<ul id="menu">
<li><a href="#animals/dog">Dogs</a></li>
<li><a href="#animals/cat">cats</a></li>
<li><a href="#shop">Shops</a></li>
<li><a href="#gangster">Gangsters</a></li>
</ul>
<div id="content-pane">No content loaded</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>
</body>
</html>

For those of you who are lazy the full example can be viewed here and downloaded here

Controlling the Controller

Below is the documented code that will run the restful ajax app. Note that I have included a service called openkeyval.org which is simplya free service for storing key pair values. It is a great example of TSA and saves me setting up a nginx/reddis server.

Hopefully the code below should be simply enough to understand. Most of you who have used a server side framework have probably experienced using Routes. Backbone.js implements routes and you should quickly read the documentation here. In the example I set up two types of routes one to catch specific urls and a standard catch all urls route. Take note of the colon and asterisk, the appended string gets turned into a variable for convenient usage in your call back functions.

Using jQuery ajax call we specify the data type as “jsonp” to circumvent the foreign cross site policy.

(function ($) {
	
	var restfulApp = Backbone.Controller.extend({
		restfulUrl: "http://api.openkeyval.org/", //This is a free service to store key pair values
		
		//Routes tell the app what to do 
		routes: {
		"animals/:animal":          "animalAction",  //This matches app/animals/* and assigns * to a variable called "animal"
		"*page":                 	"defaultAction", //This simply matches any urls that weren't caught above and assigns it to "page"
		},
		
		defaultAction: function( page ){
			if( page ) {
				//Once the default action is called we want to construct a link to our restful service
				var restfulPageUrl = this.restfulUrl + page + "page" //http://api.openkeyval.org/gangsterpage
				//Now we have a url lets get the data
				this.loadRestfulData( restfulPageUrl );
			}
		},
		animalAction: function( animal ) {
			//Once the default action is called we want to construct a link to our restful service
			var restfulPageUrl = this.restfulUrl + animal + "page" //http://api.openkeyval.org/dogpage
			//Now we have a url lets get the data
			this.loadRestfulData( restfulPageUrl );
		},
		loadRestfulData: function( pageUrl ){
			//Set the content pane to a loading screen
			$("#content-pane").text( "loading data..." );
			//Load the data in using jQuerys ajax call
			$.ajax({
				url: pageUrl,
				dataType: "jsonp",
				success: function(data){
					//Once we receive the data, set it to the content pane.
					$("#content-pane").text( data );
				}
			});	
		}

	var app = new restfulApp;
	//Initiate a new history and controller class
	Backbone.emulateHTTP = true;
	Backbone.emulateJSON = true 
	Backbone.history.start();

})(jQuery);

Demo
Source

Conclusion

Building fully ajax web apps/sites has never been easier. I cannot think of any reasons not to and I personally love the feel of a responsive non refreshing page. If you have built a hash tag web app or site before I’d love to see it so post it below.

If you see any errors or bad practises please do a pull request or simply leave a comment.

For the last example tutorial I wrote many members of the community proposed solutions in other JS frameworks. I believe this is very important as the web starts releasing more and more Javascript frameworks.


blog comments powered by Disqus