---
title: 'Jester 1.3: Jsonic REST'
teaser:
tags: news,web,javascript,jester
author: Eric Mill
published_on: 2007-06-11
---

Whew, it's been a while.  The most requested feature for Jester has been <abbr
title="JavaScript Object Notation">JSON</abbr> support, and that's what this
release delivers.  Let's get right to it.

Jester is available from SVN in [trunk
form](http://svn.thoughtbot.com/jester/trunk), or a [1.3 release
form](http://svn.thoughtbot.com/jester/tags/rel-1.3/). You can also download a
[zipped copy of 1.3](http://images.thoughtbot.com/ui/2007-6-8-jester-1.3_1.zip).
Jester is released under the MIT License.

Using <abbr title="JavaScript Object Notation">JSON</abbr> in Jester is easy.
Set the format option when defining your model, and <abbr title="JavaScript
Object Notation">JSON</abbr> will be the format used for all requests dealing
with that model.  Requests are made using .json as a <abbr title="Uniform
Resource Locator">URL</abbr> suffix.  Like so:

    >>> 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 <abbr title="Multi-Purpose
Internet Mail Extension">MIME</abbr> types.  Here's what I did:

    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 <abbr title="JavaScript Object
Notation">JSON</abbr>:

`
{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
<abbr title="Extensible Markup Language">XML</abbr> output from an
ActiveRecord::Base object includes attributes describing types, but the <abbr
title="JavaScript Object Notation">JSON</abbr> 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 or updated\_on will be turned into a
Date.

    >>> 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 <abbr title="JavaScript Object
Notation">JSON</abbr> 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.

    >>> 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 <abbr title="JavaScript Object
Notation">JSON</abbr> 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&#8212;you can pass <abbr title="JavaScript Object Notation">JSON</abbr>
information alongside an <abbr title="Extensible Markup Language">XML</abbr>
response in the same way.

A couple other small things:

* Added helper methods **updateAttributes** and **setAttributes**.  Both take a
  hash of attributes, and set the attributes of the object you're calling the
  method on.  The difference between the two is that updateAttributes() will
  immediately save the object, where setAttributes() won't.  Thanks to Floyd for
  adding these.
* It's now safe to use Prototype-style hashes (`$H`) as arguments to build(),
  create(), setAttributes(), and updateAttributes().

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.
