Jester 1.3: Jsonic REST

Posted by Eric Mill

Jun 11

Whew, it’s been a while. The most requested feature for Jester has been JSON support, and that’s what this release delivers. Let’s get right to it.

Jester is available from SVN in trunk form, or a 1.3 release form. You can also download a zipped copy of 1.3. Jester is released under the MIT License.

Using JSON in Jester is easy. Set the “format” option when defining your model, and JSON will be the format used for all requests dealing with that model. Requests are made using ”.json” as a URL suffix. Like so:

1
2
3
>>> Base.model("User", {format: "json"})
>>> eric = User.find(1)
GET http://localhost:3000/users/1.json

The controller code for this is simple. I prefer using wants.json, not wants.js, leaving the ”.js” extension available for RJS or whatever you want. This works out of the box, with no need to add a mime types. Here’s what I did:

1
2
3
4
5
6
7
def show
    @user = User.find(params[:id])
    respond_to do |wants|
      wants.xml {render :xml => @user.to_xml(:include => :posts)}
      wants.json {render :text => @user.to_json}
    end
  end

Going to /users/1.json produces the following JSON:

{attributes: {id: "1", bio: "", extra_flag: "0", middle_name: "Rogers", active: "1", created_at: "2007-04-25 19:15:10", email: "yes"}}

Note that there isn’t any automatic typecasting going on here. The default XML output from an ActiveRecord::Base object includes attributes describing types, but the JSON output doesn’t. So, boolean flags will come back as the strings “1” and “0”. At the Jester level, I’ve made two auto-casting assumptions: the ID will be turned into an integer, and any fields named created_at/created_on/updated_at/updated_on will be turned into a Date.

1
2
3
4
5
6
7
8
9
10
>>> eric = User.find(1)
GET http://localhost:3000/users/1.json
>>> eric.id
1
>>> eric.middle_name
"Rogers"
>>> eric.active
"1"
>>> eric.created_at
Wed Apr 25 2007 15:15:10 GMT-0400 (Eastern Daylight Time)

As a companion feature, Jester supports passing JSON code through the X-JSON header, passing through the second “json” parameter to any callback you provide to an asynchronous Jester request. I’ll just show you.

1
2
3
4
5
6
>>> var type;
>>> User.find(1, {}, function(eric, json) {type = json.active.type})
GET http://localhost:3000/users/1.json
XMLHttpRequest
>>> type
"boolean"

And on the controller side, inside the show action, I have this line:


    headers["X-JSON"] = "{active: {type: 'boolean'}}"

This allows you to pass extra JSON information along with any data returned from the server. You don’t have to have the model’s format set to “json” for this to operate, either—you can pass JSON information alongside an XML response in the same way.

A couple other small things:


That’s it for this round. The next major target is support for using Jester with remote websites, using iframe trickery. I’m open to adding support for server-side callbacks, but I’m not convinced it’s worth creating a server/client syntax standard for this yet, when iframes are a viable solution. If you feel differently, well this is the time to talk about it.


Comments on this post

Dr Nic

Jun 11

Dr Nic said,

Eric, I gave a plug to Jester in the keynote slides at RubyEnRails 2007 – http://drnicwilliams.com/2007/06/09/smart-people-doing-smart-things-in-netherlands-rubyenrails-2007/?preview=true

Eric Mill

Jun 11

Eric Mill said,

Thanks Dr Nic. :) And thanks for the push to keep working on Jester. Someday the world will know.


Sorry, comments are closed for this article.

© 2000 - 2009 by thoughtbot, inc.
written by a bushel of tiny robots