Developer friendly technologies

Since ToDoSo is a too important project for a single person, it appeared as important for its underlying technologies to be easily learned by external developers willing to contribute to the project.

Being a Web application, the choice is naturally limited to Web technologies and the project will likely drive the interest of developers with technical skills related to the Web.

The client-server relationship on the Web

The Web is a particular platform to work on, since it is strictly divided in two parts:

  • the server side, which refers to the part of the application hosted on a server,
  • and the client side, which refers to the part of the application that is executed directly in the Web browser of the users.

Originally, this client-server relationship was described as a thin-client: the server being the host of all the logic of the application while the client, in this case the Web browser, was a rather passive one, only able to request an URL, process the incoming HTML code into what the user knows as a Web page and sending back a request (sometime with form data) for a whole new page. Since the introduction of JavaScript in the Web browser, they evolved in smarter clients now able to dynamically and partially update the page ― known as ajax techniques (Paulson, 2005) ―, turn static Web pages into rich user interfaces ― gmail often being quoted as the pioneer of Web applications (O’Reilley 2007) ― and even use them for distributed computing (Klein and Spector 2007).

Client-side technologies

As it has already been mentioned, in addition to HTML and JavaScript, other client-side technologies are available as plugins for Web browsers, such as Flash and Silverlight. Not only have the latter ones a limited accessibility, but Web developers are also more likely to be familiar with the still prevalent Open Web technologies.

The obvious advantage of those plugins is that they provide a consistent environment across the variety of configurations that they support: a website built for Flash will be displayed exactly the same way in Internet Explorer 6 on a Windows computer as in Safari 4 on a Mac OSX computer. There are, however, numerous inconsistencies between configuration that have to be dealt with when using Open Web technologies:

  • There are different browser vendors with different implementations of HTML rendering engine and JavaScript engine. All of them are supposed to follow the w3c recommendations for HTML, CSS and the DOM interface as well as the ECMA-262 standard for JavaScript. Due to the complexity of those recommendations, the difficulty for all browser vendors to agree on them and their constant evolution ― not even mentioning the so called browser war between Microsoft and Netscape in the late 90′s (Phillips, 1998) and backward compatibility issues ―, there are unavoidable differences between the way a single Web page is interpreted in two different Web browsers, either because of an incorrect, incomplete or flawed implementation.
  • There can be different versions of a browser in use at a given time. According to Net Applications, there are currently 27% of Internet Users using IE6, 23% using IE7 and 12% using IE8. If an implementation is improved or fixed in the new version of a browser, it is therefore impossible to assume that all users will benefit from it.
  • The fonts that can be used in a Web page is still limited to the ones available in the rest of the Operating System and the displaying of the text relies on the OS capabilities. This can result in differences in the width and height of textual elements.

Dealing with JavaScript

JavaScript is the most consistent technology of this set. Although some browsers implement more recent versions of the standard, all current browsers comply with the version 1.5 of the norm, which has proven to have appropriate features for large scale Web applications.

Dealing with the DOM

In order to deal with DOM inconsistencies as well as simplifying common operations on Web pages, numerous JavaScript libraries (sometime named toolkits or frameworks) were created, the most widespread ones being Dojo, Prototype, YUI, jQuery and Mootools.

There does not appear to be any objective comparison of these different libraries in the literature. Indeed, being Open Source software, they have influenced influenced each other to a point where it is difficult, if not impossible, to pick one as the best. Their common traits are:

  • simplifying DOM traversing and manipulation, i.e. inserting, finding, moving and deleting elements of a Web page,
  • simplifying the modification of elements’ attribute such as class or style attribute to dynamically change the appearance of an element,
  • providing methods to change the style attributes of an element over time to animate it,
  • providing an unified API for ajax instead of the one implemented in w3c compliant browsers and its counterpart in Internet Explorer,
  • providing an unified API for event handling (i.e. detecting a user’s actions on a page) instead of the one implemented in w3c compliant browsers and its counterpart in Internet Explorer and providing helpers to deal with event delegation.

The library of choice for this project is jQuery, because of its clean API, its light weight and its thorough documentation. The jQuery philosophy is unofficially summarized in “Find things, do stuff“: The page is queried with a CSS selector (a mechanism that every Web developer is familiar with) and the selected elements can then be manipulated using jQuery methods.

[code lang="js"]
$("#myButton").click(function() {
$("<span>Hello World!</span>").hide().appendTo("#myParagraph").fadeIn();
});
[/code]

The previous snippet of code illustrates the different possibilities of jQuery, its conciseness and the principle of chainability: once an element has been selected in the page, different operations can be applied at once. It reads as follows:

  1. find the element with an id “myButton”,
  2. when it is clicked executes the following…
    1. create a text wrapped in a span element (this is an HTML syntax),
    2. make sure it is hidden …
    3. … before appending it to the element with the id “myParagraph”,
    4. gradually modify its opacity from 0 to 100%.

Although there are no clear statistics of the usage of the different libraries, the growing popularity of jQuery amongst Web developers, illustrated by its inclusion in the set of tools distributed with Microsoft’s Visual Studio IDE, as well as its documentation is expected to make it easier for external developers to contribute to the implementation of the client-side part of ToDoSo.

Dealing with CSS

CSS is the languages that suffers the most inconsistencies on the Web. In their latest versions, all browsers appear to be compatible with a large subset of CSS2.1, but as outlined previously, there are still around 50% of Internet users browsing the Web with older versions of Internet Explorer.

A simple solution would be to enjoin users of old browsers to update to the latest version. However, in a recent survey lead by digg, one of the largest social news Website, it appeared that 70% of those users are using IE6 because they are not allowed to install a different browser on their computer[1. Much Ado About IE6 ]. Although this number cannot be generalised, it tends to indicate that ToDoSo should be compatible with IE6 to be accessible to most users. Since ToDoSo is not expected to be publicly available before several months, a compromise could be to ignore versions of IE prior to 8 during the development phase (developers are likely to have up to date browsers) and reconsider the compatibility with older versions of IE later. Their usage share might have decreased to a point where they could definitely be ignored.

Server Side Technologies

Unlike on the client-side, there is a large variety of languages and frameworks available on the server-side to build Web applications. If any environment can be used on the server-side to create Web applications, Ruby on Rails lately pioneered the field of agile Web frameworks which seem to seduce more and more Web application developers.

The Agile Manifesto defines four leading principles (Cockburn, 2002):

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

A framework that actually allows for working prototypes to be rapidly built and for changes to be answered quickly would be highly valuable, for ToDoSo is expected to become a project opened to external contributions. The choice of server side technologies was thus limited to frameworks that shared some of the key features which make Ruby on Rails an agile framework.

  • Model-View-Controller architecture
  • Object Relational Mapping
  • CRUD for all objects
  • Routing mechanism
  • HTML templating

A simplified explanation of this technical jargon is possible with a sample pseudo-code application: a Website that allows users to view the relationships between three people: Louis, Remi and Eugene.

MVC Architecture

This design patterns makes a clean separation of the application in three layers:

  • the model defines what a person is, what relations it can have, and how those different properties are remembered in the application
  • the view in this case is the HTML page used to display the people and their relations,
  • the controller is the logic that answers to users’ requests by recalling people and relationships from the application’s memory and invoking the appropriate view to display them.

The model

[code lang="js"]
// A person is defined by its name and its gender
Person = isDefinedBy({ name: "String", gender: "Boolean" });
// A person can have a relation of friendship with another person
Person.canHave( "friend", Person );
// A person can have an enemy
Person.canHave( "enemy", Person );
[/code]

Once the memory of the application contains some person, the controller can retrieve them and pass it on the the view to produce the following output:

[code lang="html"]
<p>
<b>Louis</b> is a <em>male</em>.
His/Her friend is <b>Remi</b>.
His/Her enemy is <b>Eugene</b>.
</p>
[/code]

Such a clean separation makes modifying one of those layer safer and easier.

Object-Relational Mapping

Traditionally the people and their relationships would require two different representations in an application built with an object-oriented language and a database, typically using either Classes or SQL queries. In such paradigm, making Remi a friend of Louis is a rather complicated task:

[code lang="js"]
// Insert a Person in the database and returns its assigned id
function insertPerson( name, gender, friendId ) {
DB.execute(
"INSERT INTO 'person' ( 'name', 'gender', 'friend_id' )" +
"VALUES ( '" + name + "', '" + gender + "', '" + friendId + "' );"
);
return DB.lastInsertId;
}
// Build Remi first
remi = new Person({ name: "Remi", gender: 1 });
// Save him
idRemi = insertPerson( remi.name, remi.gender );
// Then build Louis
louis = new Person({ name: "Louis", gender: 1 });
// Save Louis while making him friend with Remi
idLouis = insertPerson( louis.name, louis.gender, idRemi );
// And later...
// Find Louis' data in the database
data = DB.execute( "SELECT ALL FROM 'person' WHERE 'id' = '" + id + "';" );
// Recreate Louis from its data
louis = new Person({ name: data.name, gender: data.gender, data.friend_id });
[/code]

Using an Object-Relational Mapping layer, the database is abstracted away and relations defined between two objects of the model can be applied directly between Louis and Remi.

[code lang="js"]
// Build and save Remi
remi = new Person({ name: "Remi", gender: 1 });
remi.save();
// Build Louis, make Remi his friend and save him
louis = new Person({ name: "Louis", gender: 1 });
louis.make("friend", remi);
id = louis.save();
// And later...
// Recreate Louis from the database
louis = Person.findById( id );
[/code]

CRUD for all objects

CRUD stands for Create, Read, Update and Delete which represents the basic operation required for the complete life-cycle of an object in the application. In agile frameworks, once an object is defined in the model, it is automatically possible to use “create”, “update” and “delete” methods on every person, “read” being available on the Person object.

[code lang="js"]
// Build Louis
louis = new Person({ name: "Louis", gender: 1 });
// memorise Louis <=> Create
id = louis.save();
// Turn Louis into a female
louis.set("gender", 0);
// Make sure this change is memorised <=> Update
louis.update();
// Get rid of Louis <=> Delete
louis.delete();
// Try to find Louis in the memory <=> Read
Person.findById( id );
[/code]

Routing mechanism

This mechanism allows for urls to be mapped to specific actions of the controller. For example, when visiting http://myapp.com/person/1, an Web page with the details of the person that has the id 1 should be displayed to the Internet user.

[code lang="js"]
personController = new Controller(function( id ) {
// Fetch data from the memory
data = Person.findById( id );
// Pass it on to the view
personView = Views.invoke( "person.html" );
personView.pass( data );
});
personController.mapTo( "/person/:id" );
[/code]

HTML templating

A template engine makes it possible to put place-holders for data of the model directly in an HTML document. Those place-holders are then replaced by the data fetched by the controller before being sent to the client.

The following template would be used to produce the aforementioned view output:

[code lang="html"]
<p>
<b><? data.name ?></b> is a <em><? data.gender ?></em>.
His/Her friend is <b><? data.friend ?></b>.
His/Her enemy is <b><? data.enemy ?></b>.
</p>
[/code]

The related controller being:

[code lang="js"]
personController = new Controller(function( id ) {
// Fetch a person from the memory
person = Person.findById( id );
// Find his friend
friend = person.getRelated( "friend" );
// Find his enemy
enemy = person.getRelated( "enemy" );
// Build the data to be passed to the view
data = {
name: person.name,
gender: person.gender,
friend: friend.name,
enemy: enemy.name
}
personView = Views.invoke( "person.html" );
personView.pass( data );
});
[/code]

Choosing an agile Framework

After spending some days looking in the literature and on the Internet, the selected frameworks were Ruby on Rails, Django (Rails’ python counterpart), Symfony (for PHP), Grails (for Java) and ActiveJS (for Jaxer).

Once again, it appeared impossible to pick one as the best. ActiveJS was finally selected for ToDoSo because, despite its lack of maturity compared to other frameworks, it had numerous features that was likely to make it easier for external contributors to adopt it:

  • it is meant to be executed by Jaxer, which is basically a Web browser stripped from its rendering engine to run on the server side. Web developers can thus leverage their client-side skills on the server-side with the possibility:
    • to access and modify the DOM on the server before it is sent to the client,
    • to share code between the client and the server sides (for safe but instantaneous form validation for example),
    • to call server side function from the client side (using invisible ajax requests)
  • it offers an abstraction not only to MySQL and SQLite databases (on the server-side) but also to client-side persistence such as Google Gears
  • its has a routing component similar to the Ruby on Rails’ one but also offers deep linking on the client side (enabling the use of the browser’s “back” button in ajax based Web applications)

Any developer able to use Open Web technologies would then find a familiar and consistent environment to work both on the server and the client side.

One thought on “Developer friendly technologies

  1. Pingback: lrbabe » Blog Archive » EventSound, round2

Comments are closed.