Supporting JSON callbacks in Rails

Posted by Dr Nic on November 23, 2006

Now you know how to write JavaScript widgets, now you need to know how to help others write widgets for your data.

Here’s a short-one act play to describe the issue at hand.

Actors in this play

You: You run a website that you built with Rails. Its got data in it. You’re a hero of the working class, a family man, and own a hybrid car, but you ride a bike to work. You vote, you contribute to the local neighbourhood newspaper, and you love Autumn because the leaves turn pretty colours. You’re not a fool.
Ulrich: Ulrich is a user of your site. Ulrich is a needy, web2.0 super-consumer. Ulrich started using your site when it was first profiled on TechCrunch, Ajaxian, and the Times magazine, but since then he’s found Theo’s website.
Theo: Theo runs a third-party website. Theo’s website has its own data too. It doesn’t have Ulrich’s data. Theo’s site wasn’t written about in TechCrunch, nor Ajaxian, nor even the local church foldover.

[Prelude] Theo just received his third email from Ulrich. Ulrich wants to port his data from Your website to Theo’s. Theo in turn, now has you on Skype…
You: I’m not very happy with the idea of giving up my data.
Theo: What happened to Open APIs? Making the user’s data transferrable with the user?
You: You read too many 37signals blog articles. Even Flickr - web two of all web two sites - doesn’t give up its data.
Theo: But some of my users…
You: You mean Ulrich. He’s emailed me too
Theo: Yeah, Ulrich. Ulrich wants to embed his data from your site into my site.
You: We already have a JSON API..
Theo: Its no good.
You: Works just fine. Returns lovely JavaScript data. Our users use it within our site to write their own widgets. Its one of our big draw cards.
Theo: Its no good. It doesn’t support callbacks.
You: What the?
Theo: Without a callback function there is no way my <script> tags can trigger any functionality when they retrieve the data. Ulrich could include his JavaScript widget into his page on mysite with your data if it was possible to specify a callback function in your API.
You: Instead of just raw JSON data?
Theo: Yeah. Lots of other sites offer it: CoComment, Delicious, Google Data, etc. They all allow callback=myFunction in the URL parameters.
You: [thinking to yourself] Rails don’t support callbacks out of the box. Bugger.
You: Sure, I’ll work on something.
Theo: Thanks, hopefully this gets Ulrich off my back. Should drive us both more traffic too.
You: The wikipedia page for JSON doesn’t mention callbacks.
Theo: Its a wiki. Add it yourself.
You: Smart arse.

The end.

Supporting JSON callbacks in Rails

Piece of cake.

But first, to support pure JSON API data objects from Rails, you have a handy to_json method on the Object class. So, in the partial/view you are rendering, e.g. person_json.rhtml (or person.rjs if you using MinusR plugin), you include:

<%= @object.to_json %>

Yeah, that was tough.

Now, for callback support. Change the above to:

<%= “#{params[:callback]}(” if params[:callback] -%>
<%= @object.to_json -%>
<%= “)” if params[:callback] -%>

Done.

Update: render_json method

Tim Lucas wrote a great article introducing a render_json method to add to your base ApplicationController. It will automatically return JSON data that you pass it, wrapped automatically in a callback or assigned to a variable (or both) if the parameters include a callback or variable value.

Read it, its good.

Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. Mr eel Fri, 24 Nov 2006 01:56:34 UTC

    Nice!

    I’ve never even thought about callbacks when consuming JSON. Nice example mate :)

  2. Tim Lucas Fri, 24 Nov 2006 02:57:19 UTC

    I just created a render_json method in ApplicationController to perform the same thing…. no need for MinusR.

  3. Dr Nic Fri, 24 Nov 2006 07:37:43 UTC

    @Tim - ahh thanks for the link. That solution looks really thorough. It might be more Rails-Fu-ish if render_json became render(:json => json, options), but that could be me being anal.

    All in all, wonderful!

  4. Michael Daines Fri, 24 Nov 2006 08:12:42 UTC

    render :json => whatever, :callback => "myFunction" would be even nicer.

  5. Dr Nic Fri, 24 Nov 2006 08:36:39 UTC

    @michael - the nice part about Tim’s current render_json function is that it auto-detect’s callback and variable parameters, instead of explicit options.

  6. Tim Lucas Sat, 25 Nov 2006 00:43:24 UTC

    @Nic: ooooh yes, render :json => @something.to_json is definitely up on the sexy factor. I’ll be needing to add JSON-P to the project I’m currently on, so I might in fact do that and wrap it up as a plugin.

    Thanks Nic!

  7. Dr Nic Sat, 25 Nov 2006 06:37:00 UTC

    @Tim - that sounds great!

  8. Chu Yeow Wed, 06 Jun 2007 11:38:58 UTC

    Nice writeup! I never thought of providing JSON callbacks before I read your entry.

    I did notice Rails now provides a :callback option when you do a render :json (for anyone coming to this old post), e.g.:
    render :json => {:name => "David"}.to_json, :callback => 'show'

Comments