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.
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.
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:
GetID
should be simply id
.wave_id
inside of WaveData
. I believe that this should simply be id
_ContextImpl
. I moved the underscore to the end because Ruby doesn’t allow classes to be named this way.type
. This is a PITA in Ruby as there is an existing (and deprecated) attribute by this name._
, __
, and InitialCaps
for functions implemented as defacto naming conventionsOverall, 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.
I guess that explains why they recommended using their libraries and warned that the underlying protocol would change. They wrote it so Java could easily talk to Java, and put off making it language-neutral till later.
I certainly hope so anyways. It’d suck if it stays that way.