JSON-P on Rails with JQuery

Posted by acts_as_flinn Sun, 20 Apr 2008 17:22:00 GMT

JSON-P based Comment

Over the last several months I’ve had the pleasure of developer JSON based commenting solutions for publishers. I couldn’t be happier using JSON as a transfer method for moving ActiveRecord based object from the database almost directly to the consumer. I’ve run into some difficulties here and there mainly due to the Same Origin Policy which is a bastard of a browser rule that makes sending JSON across domains difficult. Even though prototype.js seems to support sending requests across domains there is no native script transport in prototype and worse yet it appear some browsers won’t allow AJAX across subdomains to overcome the SOP rules. I searched all over the web and found a few hacks for adding the script tag to prototype.js but I found the best solution was built native into JQuery’s getJSON. I was really taken with JQuery’s ability to handle the script transport method out of the box but I think even more I’m taken with JQuery’s syntax. I had a conversation with Less Everything’s Steven Bristol about 6 months ago and he asked if I had checked out JQuery. I had briefly looked at it but I wasn’t wowed by it (probably because I didn’t use it on a project). Steven: “isn’t it the best thing you’ve ever seen?” Me: It’s ok. (*my answer to everything – ask my wife). Six months later I get to use it on a project and my answer to you Steven is YES it is the greatest.

JSON-P

Back to the subject… So the problem is that a browser doesn’t want to send a request across domains for fear that your secret info will be compromised by some would be hacker. The solution JSON padded with a callback method combined with a plain old script tag aka JSON-P. With JQuery the idea is that you can pass a URL into JQuery’s getJSON method with a ? for JQuery to bind it’s on changing function name that handles a callback. Sound like a hack? Yes but everyone is doing it. I’ve seen some skeptics but overall this is an accepted solution. And until JSONRequest is accepted as a safe cross site transport JSON-P is here to stay.

Does Rails support JSON-P?

Bet your ass it does. Right out of the box Rails supports the callback option to be passed in on a :json render. Like so:

render :json => @comments, :callback => params[:callback]

JSON-P Problems on Rails

So the issue you’ll run into primarily with JQuery is the changing name of the callback. JQuery binds a random function name to the request (presumably to protect from attacks of some sort, maybe for anti caching). The issue is that with action caching caches the entire response body meaning the next call has a stale cache (because of the now changed callback name) or has to generate a new response for a new callback name. While JSON is typically very light weight the to_json method can be expensive and when you’re dealing with high traffic situations you always want to squeeze every bit of performance out that you can. We also do paginated result sets with will_paginate so it means there is a bit of post processing after a plain old find_all_by_blah… The solution I’ve been using is a mix of cache_fu for model level caching along with fragment caching the to_json results then interpolating the cached json into the callback. Sound like a hack? It is but it feels a bit better when you crunch out over 500/reqs/s as opposed to 14/reqs/s.

For the future

Let’s cross our fingers for CouchDB. I’ve been experimenting with Couch over the last week or two and I’m really pleased with the possibility of a RESTful document based database with native JSON and coming support for MapReduce. The future looks bright, I can imagine not so distant support for native ruby object level persistence. Yay!

AJAX Tabs (Rails redux)

Posted by acts_as_flinn Sun, 25 Feb 2007 09:12:00 GMT

A while back I wrote a tutorial on AJAX Tabs as a plug for a PHP clone of Ruby on Rails called Biscuit. Well Biscuit is long gone, but the I still use the tutorial code, but just in Rails. So I came up with an update using Rails. Check out the Ruby on Rails AJAX Tabs Tutorial.