Wednesday, June 15, 2011

GWT RequestBuilder vs RPC vs Script-Include

Which should we use: GWT RPC or RequestBuilder?

GWT presents four ways to perform async data transfer with the server.

  • GWT RPC
  • RequestBuilder
  • javascript include
  • the new-fangled ORM-friendly RequestFactory

GWT RPC is built on XMLHttpRequest (look up wikipedia on that) and therefore suffers the restriction of SLD SOP (Second level domain Same origin policy). I wrote a description of this at http://h2g2java.blessedgeek.com/2009/08/gwt-rpc.html. No doubt, newer browsers including IE 8 have a non-w3c-sanctioned XDomainRequest but I doubt GWT RPC has acquiesced to that new development.

RequestBuilder
RequestBuilder is also built on XMLHttpRequest. The difference between the two is that GWT RPC is an elaborate framework to define the client-server communication channel utilizing interfaces to provide Serializable POJO (plain old Java objects) transfer of data. Whereas RequestBuilder is simpler and more palatable to the usual adhoc-quick-and-dirty programmer. RequestBuilder requires you to concoct your own object data structure marshalling/demarshalling because you have to pass your data as String. But then you could encode the data structures using GWT's JSON marshalling/demarshalling routines. You can find my routine in Google Code to perform JSON data-transfer at http://code.google.com/p/synthfuljava/source/browse/trunk/gwt/http/org/synthful/gwt/http/client/JsonHttpResponseHandler.java

Is it true that GWT RPC actually calls RequestBuilder? I need to pace through the debugger to confirm that. I think I have already done that sometime before that confirms that GWT RPC actually calls RequestBuilder. GWT RPC uses its own esoteric encoding, and the format of POJO serialization is deliberately obfuscated.

JSON & JSONP
To transfer data using Javascript script include would require the data to be Javascript objects, obviously. And they Javascript objects would be stringified into text representation. Text representation of Javascript objects is JSON. You could send data to the server using JSON or whichever format that has been agreed upon between your GWT client and the server. However, the server needs to return data to your GWT client in JSONP.

JSONP is actually a Javascript function encapsulating the Javascript objects as its arguments. When the server sends your GWT cllient data using JSONP, it is actually attempting to execute a Javascript function. Therefore, that function would need to be predefined before receiving the JSONP data.
There are two ways that could happen:

  • The server sends a JSONP defining the function.
  • The client defines the function before sending the request.

Concurring the JSONP callback function with the server.
A general and his adjutant awaits to attack, each of their divisions on a different hill 10 miles apart. Their cloud of enemy is at the valley below them. The adjutant and the general agrees beforehand a set of orders correlated to a set of keywords. One of the orders could be like - attackFromLeft(orderDetails).

Similarly, the client would have predefined the Javascript callback function displayBarChart, and the data structure barChartDetails:

function displayBarChart(barChartDetails) { ... ...}

before sending a request to the server that would trigger receiving the data from the server:

displayBarChart({
  categories:[
    rambutans:{price:30, unit:kg},
    durians:{price:50, unit:pounds}
  ]
});

Script include to the rescue
Since, GWT-RPC uses its own esoteric encoding rather than JSONP, I can hardly see the possibility of its performing cross-domain GWT client-server communication.


To circumvent the SLD SOP restriction, whether in Javascript or any means of AJAX, you have to use the Javascript script include technique. i.e., < SCRIPT SRC='...' > tag. You could read my code on how to do that in the class JsonRemoteScriptCall at http://code.google.com/p/synthfuljava/source/browse/trunk/gwt/jsElements/org/synthful/gwt/javascript/client/JsonRemoteScriptCall.java.

This piece of code works on the browser DOM by dynamically defining a SCRIPT element in the DOM.

Script include is hazardous
Be duly warned that script include

<SCRIPT SRC=some-url ...></SCRIPT>

is hazardous in terms of security. Script include, like image include, allows your client to get resources from any server in the cloud that is willing to serve data to your client. And there will be no shortage of servers maliciously defining a Javascript function in the script.