intertwingly

It’s just data

Wave Robot Ruby Client


Wanting to learn more about Google Wave, I ported the Wave Robot Python Client library to Ruby, mainly because I wanted to understand the protocol.  The current protocol is tightly coupled to the Java server implementation.

>>> import waveapi.document
>>> import waveapi.util
>>> waveapi.util.Serialize([waveapi.document.Image('http://example.com/foo.jpg', width=100, height=100)])
{'javaClass': 'java.util.ArrayList', 'list': [{'type': 'IMAGE', 'properties': {'javaClass': 'java.util.HashMap', 'map': {'url': 'http://example.com/foo.jpg', 'width': 100, 'height': 100}}, 'java_class': 'com.google.wave.api.Image'}]}

In addition to being littered with javaClass names and requiring 5 levels of nesting to represent an array of a single Image, this serialization is not strictly JSON as it uses single quotes, something that the builtin library for Ruby chokes on:

$ irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'json'
=> true
irb(main):003:0> JSON.parse('["foo"]')
=> ["foo"]
irb(main):004:0> JSON.parse("['foo']")
JSON::ParserError: 349: unexpected token at ''foo']'

But, in any case, the Ruby implementation can now match the function:

$ irb
irb(main):001:0> require 'document'
=> true
irb(main):002:0> Util.Serialize([Image.new('http://example.com/foo.jpg', :width=>100, :height=>100)])
=> {"list"=>[{"java_class"=>"com.google.wave.api.Image", "type"=>"IMAGE", "properties"=>{"javaClass"=>"java.util.HashMap", "map"=>{"url"=>"http://example.com/foo.jpg", "height"=>100, "width"=>100}} }], "javaClass"=>"java.util.ArrayList"}

Other than the use of double quotes and the ordering of Hash keys, these results match.

Additional notes, in no particular order:

Overall, I feel that this Google Wave could benefit from earlier and wider reviews.  In particular, the whole approach to JSON generation should be rethought.  I look forward to testing interop with a live server, in particular one that I can self host.