Jaxer + Persevere via Dojo’s JsonRestStore

By on September 29, 2008 9:43 am

perseverejaxerdojo.png With the increasing popularity of JavaScript, and rising usage of JavaScript in the browser, it is becoming very effective to use JavaScript on the server to have a single end-to-end language for both client and server-side development. Options for server-side JavaScript are also increasing.

Jaxer is a new server that uses server-side JavaScript for HTML generation, using the standard browser DOM model (it is actually running Mozilla’s engine on the server) as the API. Persevere is a JavaScript based database system, that integrates a JavaScript based object model with object persistence. Dojo‘s new PersevereStore, which is built on the JsonRestStore, allows code running in Jaxer to easily query, manipulate, and interact with data in Persevere by running Dojo on Jaxer’s server-side JavaScript environment. These two JavaScript servers can complement each other, with Jaxer providing HTML presentation/generation and Persevere providing the data object model and persistence, with JsonRestStore as the bridge.

Getting started with Persevere and Jaxer is simple, just download, unzip, and start Persevere with java -jar start.jar, and Jaxer with the StartServers script. First, for our example we will create a new table in Persevere. You can go to the Persevere browser, which should be accessible at http://localhost:8080/browser.html?id=root on your local machine, and click the plus sign to add a new table. We will call it “Contact” (and accept “Object” as the super type). Next, click on Contact, select “data”, and click the “Add list item” button and create a new object. Select the new object and add “name”, “email”, and “phone” properties. You can alternately create a new contact at the console by entering:

var newContact = new Contact();
newContact.name = "John";
newContact.email = "john@doe.com";
newContact.phone = "345-343-3333";
commit();

Or the equivalent object creation can be done with an HTTP/REST request:

POST /Contact/

{"name":"John",
 "email":"john@doe.com",
 "phone":"345-343-3333"
}

Next, you need to add Dojo to Jaxer’s web directory at /jaxer/aptana. You can download Dojo or use the Dojo build included with Persevere (this is not a full build of Dojo, just the components needed to interact with Persevere). We will be running Dojo in Jaxer’s server-side environment. Now we can create a page using Dojo’s PersevereStore (once again, just a slight extension to JsonRestStore) to connect to the Contact table:

	
	
	

Now we can easily query the table, we will do an empty query to get all the objects in the Contact table:

var results = contactStore.fetch({}).results;

And now we have the result set from the database and we can generate HTML with it:

var content = dojo.byId("content");
dojo.forEach(results,function(item){
	var tr = document.createElement("tr");
	var td = document.createElement("td");
	td.appendChild(document.createTextNode(item.name));
	tr.appendChild(td);
	var td = document.createElement("td");
	td.appendChild(document.createTextNode(item.phone));
	tr.appendChild(td);
	var td = document.createElement("td");
	td.appendChild(document.createTextNode(item.email));
	tr.appendChild(td);
	var td = document.createElement("td");
	td.appendChild(document.createTextNode("Send a message to the contact"));
	tr.appendChild(td);
	td.setAttribute("onclick","sendMessage('" + item.id + "')");
	content.appendChild(tr);
});

Of course, this is the hard way to generate HTML, in a previous post we demonstrated how you can use the Django template library engine included with Dojo to do templating within Jaxer.

The PersevereStore has a full read/write Dojo Data API, you can create, update, and delete objects as well as querying, all from the Jaxer server-side JavaScript environment:

// create an item:
newItem = contactStore.newItem();
// create/modify a property
contactStore.setValue(newItem,"name","Jane");
// save the changes to the database
contactStore.save();
// delete an item
contactStore.deleteItem(newItem);

You may have noticed in the last line in the DOM creation that we included an event handler, we can register to have the onclick event trigger another server-side execution. In our example, we called sendMessage with the id of the contact. We can create a sendMessage function in our page to run on the server to handle this event. We will use this function to demonstrate how we can further interact with Persevere from Jaxer. Persevere is more than just a data storage server, it allows you to create methods and property types for the objects within each table. We can create a sendMessage method for the Contact table; all the objects in the store will then have a sendMessage that can be called through JSON-RPC. We can create a JSON-RPC request to trigger this method in Persevere from Jaxer:

function sendMessage(id){
	var xhr = new XMLHttpRequest();
	xhr.open("POST","http://localhost:8080/Contact/" + id, false);
	xhr.send(Jaxer.Serialization.toJSONString({
			method:"sendMessage",
			id:"call",
			params:["hi there"]
		}));
	alert("sent email");
}

In order to add this method to the Contact objects, we add a function to the Contact.prototype just as we would normally do in JavaScript. We can do this from the console in Persevere:

Contact.prototype.sendMessage = function(message){
	var fullMessage = "Hi " + this.name + ",\n" + message;
	com.myapp.sendEmail(this.email, fullMessage);
	this.contacted = true;
}

Or use the equivalent HTTP/REST request:

PUT /Contact.prototype

{
  sendMessage: function(message){
  	// we can read properties from this persisted object like the name
	var fullMessage = "Hi " + this.name + ",\n" + message;
	// we can interact with the Java environment 
	// since Persevere runs on Rhino/Java
	com.myapp.sendEmail(this.email, fullMessage);
	// we can modify this object and the changes are automatically persisted
	this.contacted = true;
  }
}

Here we built a model method that can directly integrate with the persisted object data, and can interact with Persevere’s Java environment. In Persevere methods can leverage the vast array of Java libraries that are available from JavaScript (via Rhino).

Now when we click on the “send a message to the contact”, Jaxer will handle the Ajax interaction, and then trigger the method on the Contact object to send a message for that object. Our application can utilize Jaxer’s full DOM API for HTML generation/presentation on the server, and leverage Persevere for the data model and storage. The business logic can integrate closely with the data model, and the presentation layer can be properly separated, in this example, handled by Jaxer.

Download this Jaxer HTML Demo (this is the full source, it has not been executed/generated from Jaxer). The combination of Dojo, Jaxer, and Persevere allows developers to do end-to-end JavaScript development from the browser to the server HTML generation to the business logic and persistence end with consistent approach and language throughout.