Groovy Interchange Format?

Is Groovy a good way to pass complex data from one server to another (instead of JSON or XML)?

I’m in the process of developing some servlet-based graphs and need to pass complex data to the graph so that it has enough information to draw a scatter chart and overlay this with an image map so that the user can hover over and click on the individual data points.

The way I want it to work is to have a stand-alone image producing servlet and pass it a data URI in the request which it can open and get the data it needs.

There are a number of different ways I could use to encapsulate this data:

  • I could pass Java objects of some class, but then I would have to pass some sort of query in the URL so that the server can get the right objects to display. It would be difficult to decouple the graphics from the data server using this approach. And it certainly wouldn’t work from one server to another.
  • I could use XML and pass the servlet could parse the XML and have all the data that it needs. This would seem to be the “standard” approach. But parsing XML isn’t cost free both in terms of time or programming effort, so though it’s a well-understood problem, I’m not jumping to choose it.
  • I could use JSON. This seems quite a neat approach and I’ve looked at other Graph generating solutions (for example Open Flash Chart). There’s the easy to use JSON Tools that would make this OK. But you still have to walk through the JSON Tools objects and extract the data.
  • Or, since I’m already using Groovy on this project, I could use Groovy.

The advantage of using Groovy is that, like JSON, it’s very easy and pretty compact to write. The sort of data I’m looking at is:

[
    points: [[10, 10, "Visit 1", "javascript:alert('Visit 1')], [10, 40, "Visit 2"], 
             [40, 10, "Visit 3"], [40, 40, "Visit 4"]],
    xLabel: 'Waiting Time',
    yLabel: 'Cost per visit'
]

So effectively, I’m creating a simple Map (for the points I’m using a list because the order may be significant).

It’s extensible because I can add new keys and values (though the same applies to XML or JSON). But the best bit is that in order to parse it, all you have to do is:

    GroovyShell shell = new GroovyShell();
    Map data = (Map) shell.evaluate(groovyData);

    String yLabel = (String) data.get("yLabel");
    ....

Obviously, this is a simplification because I need to check that the Groovy is well formed, parsable and in the format that we expect, but it isn’t any more difficult than it would be in XML or JSON.

Any thoughts or comments on this approach would be welcome!

7 thoughts on “Groovy Interchange Format?”

  1. Pingback: Web 2.0 Announcer
  2. Thats actually pretty cool because it parses directly into a Java object which can then be used by Java classes. I’d like to see a performance comparison of using this, vs parsing JSON. It might be faster, but, on the other hand, Groovy isn’t exactly known for its speed.

    The primary disadvantage is that its not a widely used standard, so the next person to see the code might be thinking WTF?, even if, technically, its a good solution. It would probably gain more acceptance if you came up with a cool acronym for it, though, along the lines of JSON or AJAX. Maybe GrIF?

  3. Hi Spike, I love “GrIF”!!! I’ll get on to ISO straight away!

    You’re point about the parsing speed is interesting. It shouldn’t be too difficult to test out either. As for not being widely used, that’s right too, but this particular application uses Groovy and Groovy Server Pages already. So actually what happens is that a GSP generates the data in GrIF and the graph servlet consumes it.

  4. Hmmm…

    Rather than writing out the Groovy as a string, which forces you to check that its well formed, parsed, and, correctly formatted, it might be better if you had an object to handle that for you.

    I’m thinking you could do something like this:

    GrIFMap grifMap = new GrIFMap();
    grifMap.add(“points”, [[10, 10, “Visit 1”, “javascript:alert(‘Visit 1’)], [10, 40, “Visit 2”],[40, 10, “Visit 3”], [40, 40, “Visit 4”]]);
    grifMap.add(“xLabel”,”Waiting Time”);
    grifMap.add(“yLabel”,”Cost per visit”);

    Then, to get the correctly formatted data string out, it would be a call to:

    groovyData = grifMap.toGrIF();

    Then, on the other side of the wire, you could do:

    GrIFMap map = new GrIFMap(groovyData);
    assert “Waiting Time”.equals(map.get(“xLabel”));

    The fact that its Groovy going over the wire would be basically invisible to the rest of the implementation. I’d probably extend GrIFMap off of LinkedHashMap, to maintain data order….

    Cool stuff.

  5. Nice idea, but Groovy maps don’t serialize nicely. Strings are double-quoted, so they will be interpreted as GStrings, so embedded dollar signs will be a problem. Dates, enums simply get written out unquoted. The result is not valid Groovy:

    enum Floo { x, y }
    def m = [a:new Date(), b:’$hi’, c: Floo.x]
    println m

    Result: [“a”:Thu Dec 04 12:13:17 EST 2008, “b”:”$hi”, “c”:x]

Leave a Reply

Your email address will not be published. Required fields are marked *