Dr Nic

Supporting JSON callbacks in Rails

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.

Related posts:

  1. Instant new Rails applications with the App Scrolls When I start a new project I want to start...
  2. Using CoffeeScript in Rails and even on Heroku I’m pretty excited about CoffeeScript as a clean-syntax replacement for...
  3. First look at rails 3.0.pre This article is out of date in some aspects....
  4. Rails themes can remember things I was getting annoyed at having to remember all the...
  5. Install any HTML theme/template into your Rails app Have you ever even bothered to Google for “rails...

10 Responses to “Supporting JSON callbacks in Rails”

  1. Mr eel says:

    Nice!

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

  2. Tim Lucas says:

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

  3. Dr Nic says:

    @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. render :json => whatever, :callback => "myFunction" would be even nicer.

  5. Dr Nic says:

    @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 says:

    @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 says:

    @Tim – that sounds great!

  8. Chu Yeow says:

    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'

  9. get rid of that god damn hire ad! says:

    i immediately blocked it with adblock cause anything that doesnt move is annoying

  10. Dr Nic says:

    Sorry about that. When I get bored with it I’ll take it down.