RAP protocol: JSON messages

May 10, 2010 | 5 min Read

In a previous blog I talked about the functionality that a RAP protocol message should provide. I also introduced you to the requirements of a message. A message should take care about the following tasks: Construction, Destruction, Synchronization, Eventlistener, Events, Methods and Scripting (look at this blog for more details). Additional a message should provide request and display relevant information. So, I decided to search for a messaging format which is able to bring the described information into one message. The result of this search is JSON. JSON is a very lightweight messaging format defined by Douglas Crockford and eliminates the drawbacks of XML. The cool thing about JSON is that it’s really fast to parse a message and it’s very readable by humans. Another cool thing is that it fits all needs of the RAP protocol. So, now lets take a look at a sample protocol message:

{
  "meta" : {
    "settingStore" : 123486875,
    "requestCounter" : 6,
    "tabId" : 4
  },
  "device" : {
    "id" : "w1",
    "cursorLocation" : [ 214, 544 ],
    "focusControl" : "w34"
  },
  "widgets" : [
    {
      "widgetId" : "w23",
      "type" : "synchronize",
      "payload" : {
        "prop1" : "value1",
        "prop3" : "value2"
      }
    },
    {
      "widgetId" : "w33",
      "type" : "listen",
      "payload" : {
        "selection" : true,
        "focus" : false
      }
    },
    {
      "widgetId" : "w24",
      "type" : "construct",
      "payload" : {
        "parent": "w33",
        "widgetType" : "org.eclipse.swt.Text",
        "style" : [ "BORDER", "FLAT" ],
        "parameter" : [ "eins", 2, true ]
      }
    },
    {
      "widgetId" : "w25",
      "type" : "fireEvent",
      "payload" : {
        "event" : "focus-in"
      }
    },
    {
      "widgetId" : "w26",
      "type" : "destroy",
      "payload" : null
    },
    {
      "widgetId" : "w27",
      "type" : "execute",
      "payload" : {
        "method" : "someName",
        "parameter" : [ "value1" , "value2" ]
      }
    },
    {
      "widgetId" : "w44",
      "type" : "executeScript",
      "payload" : {
        "scriptType" : "text/javascript",
        "script" : "var wm = org.eclipse.swt.WidgetManager.getInstance();"
      }
    }
  ]
}

The above message example shows an imaginary RAP message. The sample make no differences between request and response. Now lets take a closer look at the meaning of the message.

As you can see the whole message is represented as one JSON object. Let us call this object the “message” object. The message object has three properties: “meta”, “device” and “widgets”. Two of these properties are also represented as objects. The “meta” and “device” objects are simple property maps for the request and display specific information. The interesting part of the “message” object is the “widgets” array. As you can see the array is an object array. This means the containing array properties are JSON objects. With the use of an array instead of an object we can bring an order to the containing information which is needed for reproducing e.g. an event order on the server side. Each object in the array represents one widget payload. The payload types map the needed functionality. The following payloads are valid:

  • synchronize: For synchronizing widget properties.
  • listen: For adding a listener to a client side widget.
  • construct: For creating widgets on the client side.
  • fireEvent: For firing client side events.
  • destroy: For disposing client side widgets.
  • execute: For calling a method on a client side widget.
  • executeScript: For executing native script code.

Each object in the widget array has three properties. First the “widgetId”. The id is needed to identify the client side counterpart of a widget. The second property is the “type” of the payload (one of the seven above). The “type” property identifies the content of the “payload” property. The “payload” property is normally another JSON object which has “type” specific properties. For example a “widgets” array object of the type “synchronize” holds a map of properties within it’s “payload” object. I think the other types are almost self-explanatory.

I think this is a very straight forward message structure which makes it very easy to understand messages that are sent from the RAP server to the client and the other way around. For sure you have to understand JSON. But I think JSON is very easy to understand and widely used across the web. So, in my opinion JSON is the right choice for the messaging format. With JSON we can completely wrap the required information and it’s free of any meta overhead. Another pro for JSON is very obvious when you look at a message that’s currently sent from the RAP server to the client. So, the described example message is much more meaningful than the RAP generated JavaScript code listed below (normally it’s all in one line).

var wm = org.eclipse.swt.WidgetManager.getInstance(); wm.dispose( “w306” ); var req = org.eclipse.swt.Request.getInstance(); req.setRequestCounter( “3” ); var w = new org.eclipse.rwt.widgets.ToolItem( “check”, false ); wm.add( w, “w317”, false ); var t = wm.findWidgetById( “w286” ); t.addAt( w, 0 );w.setText( null ); w.setImage( “rwt-resources/35.fwk14856315/icons/ttt.gif”, 16, 16 ); w.setSpace( 0, 24, 0, 22 ); w.setHasSelectionListener( true ); wm.setToolTip( w, “Filter all leafs” );

To improve the message quality let me know what do you think about the described format please. Any feedback is very welcome. As a next step I will create a prototype for creating this kind of messages in the context of RAP. I will talk about the structure of this generator as soon as I have results ;)