Building an API into a Rails app

PLEASE READ ME Many people are Googling for Android and iPhone Ravelry apps and finding this post from last year. What happened to the iPhone app? Will there be an Android app? You can find the answers to these frequently asked questions over on Ravelry: http://www.ravelry.com/discuss/for-the-love-of-ravelry/topics/1465110#2


Original post (old!)

So.. we’re working on a iPhone app. Ravelers, just like the users of most other sites, are clamoring for one. It’s not just that, though – we think that Ravelry will make a great mobile app and that being on the iPhone will be a really good thing for us.

Adding a full featured API to the site has been a really good exercise. It’s really helped me to improve code quality and tie up loose ends and I’m glad that the iPhone has finally sparked the creation of an API for Ravelry.

I was surprised to find that the software support for API needs is lacking in places. Here are some of the missing or ill-fitting pieces that I’ve run into so far:

Routes, controllers and actions

Rails gives us formats and :respond_to. Rails 3 makes it even better…. but I don’t like it. I don’t like mixing my API actions up with my non-API actions because the logic is never the same except for the simplest methods. For now, I’m just manually adding routes that send my API (JSON) requests to X_with_api actions. Hopefully some sort of pattern will emerge and an idea will sprout… or maybe I’ll see the error of my ways.

Documentation

I couldn’t find any way to generate pretty API documentation from simple structured text or code comments. There are so many people creating and documenting HTTP APIs that I was a little surprised by this. For now, I made up a code commenting convention and borrowed heavily from YARD. I could try to figure out a way to get YARD to parse the stuff but I suspect I’ll end up hacking up a simpler parser that generates HTML documentation.

I like that this combined with the above results in methods dedicated to each API call with code comments that describe the HTTP parameters and JSON output. Add in a little setup code and some sample parameters and I could probably create tests from this.

Rendering the Results

For now, I’m only providing JSON. When I first started out, I was wishing for some XML::Builder/rxml like thing that I could use to write templates that generated JSON. My wish has since been granted by the Tequila RailsRumble project but I’m glad that I ended up going in a different direction.

I’m using my own take on the serialize_with_options plugin. This allows me to set up multiple serialization “styles” (for example, I might have “compact” and “normal” – for search results vs retrieving a full object) and declare what attributes, method return values, and associated objects to include. I’m liking this approach so far: it means that all of my API data has to be in a model as a method or attribute which will be easier to maintain. It also results in a little DSL that I should be able to use to generate API documentation that describes the return values.

That’s what I’ve got so far. It’s my first time building such a full-featured API and it feels a little like I’m inventing things that I shouldn’t have to invent. At least what I’ve got so far seems like it will be easy for me to maintain. I’m just getting started, so who knows where I’ll be by the end.

Comments (37)

  1. Jeff Putz wrote:

    Is there an easy way to serialize JSON in the iPhone SDK? How do you feel about networking in general?

    I’ve tried several times to jump in to it, but Objective-C seems to take ten steps backward from modern languages and I just can’t get in to it.

    Thursday, September 3, 2009 at 10:51 pm #
  2. easco@mac.com wrote:

    Is there an easy way to serialize JSON in the iPhone SDK?

    Not directly in the SDK that I’m aware of. At Quickoffice, we use the open source JSON parser in Google’s open source code base to parse and generate JSON. It works with NSDictionary and NSArray classes and handles most common basic types (like NSNumber) pretty well.

    http://code.google.com/p/json-framework/

    Friday, September 4, 2009 at 7:20 am #
  3. David Ross wrote:

    Good luck with your iPhone app development and launch! If you open the API to third-party developers I’d definitely be interested in checking it out.

    Best, Dave KnitBuddy developer

    Friday, September 4, 2009 at 12:45 pm #
  4. KelleBelle wrote:

    Argh. Gonna hafta get an iPhone now if I can get a Rav app for it. Damn you codemonkey!! :)

    Friday, September 4, 2009 at 2:08 pm #
  5. Adam Dill wrote:

    What I’ve been doing lately for API calls is to put a Rack application in front of the Rails stack, usually at something like /api/ and doing all the API calls through those.

    i think rack (sometimes with sinatra) is better (and certainly faster) at handling those types of requests.

    an alternative method is to put a sinatra metal application, and bypass everything but the router for that, and use sinatra’s routing handlers for it, inside of the metal app

    Monday, September 28, 2009 at 9:51 am #
  6. Ruth Krueger wrote:

    Ooo…I Googled “ravelry iphone app” and stumbled upon your page! Please tell me it’s true? I’m dying for a knitting app that pulls my info from Ravelry and let’s me keep track of my projects in progress (count stitches, rows, repeats, like KnitBuddy).

    Monday, September 28, 2009 at 2:35 pm #
  7. Alix wrote:

    So excited for this!

    Friday, October 9, 2009 at 4:13 pm #
  8. Bleubarrie wrote:

    KelleBelle,

    Get an iPod Touch instead! What AT&T’s got going on with the iPhone is highway robbery–$80/mo for service! Sure, the iPhone is great if you want to be able to get directions and navigate while on the road, but I love my iPod Touch for everything else as I can get WiFi just about anywhere I go. For voice service I still use my dumb old feature-poor clamshell–it does the trick and is a helluva lot cheaper since I don’t talk all that much and use prepaid.

    Just about any iPhone app can be installed on the iPod touch as well, as long as it doesn’t require a microphone or 3G. Can’t wait for the Ravelry app for my iPod touch!

    Friday, October 30, 2009 at 2:28 pm #
  9. Nicole wrote:

    Would you ever consider an android app as well? I’m a Mac person, but need to be on Verizon, so I’m crossing my fingers!

    Monday, November 9, 2009 at 11:07 am #
  10. Lesley Perg wrote:

    Seconding the Android app. I wish that apps were more portable. Apparently there are programming systems where you can write the code once and then compile both for iPhone and Android, but it must be kludgy since it never seems to happen.

    Thursday, November 19, 2009 at 4:11 pm #
  11. How do we become a beta tester for the app? So glad to hear you are working on this!

    Saturday, November 21, 2009 at 11:08 am #
  12. geckoknits wrote:

    I second the offer to be a beta tester!

    Tuesday, December 1, 2009 at 11:43 pm #
  13. Also interested in helping with the beta testing.

    Friday, January 15, 2010 at 4:54 pm #
  14. ravelry app wrote:

    I would love to beta test iphone app for ravelry.

    Sunday, January 17, 2010 at 11:50 pm #
  15. Rachel wrote:

    I’m a SQA engineer and would also love to help beta test!

    Tuesday, February 23, 2010 at 11:02 pm #
  16. Sarah wrote:

    I use an iPod touch and would gladly (and curiously)help beta test. I know another Ning site, GovLoop, just published their app so maybe that could help you along?

    Tuesday, March 30, 2010 at 12:14 pm #
  17. Holly wrote:

    A third vote for the Android app. I too need to be on Verizon but would LOVE an Android app. crosses fingers

    Saturday, April 17, 2010 at 9:49 pm #
  18. Ann S wrote:

    Add me as another who votes Android. I just got an HTC Incredible and I think a Ravelry app there would rock.

    Thursday, May 6, 2010 at 7:31 pm #
  19. Casey wrote:

    Sorry Android people – there just aren’t enough android toting knitters to make it worth the effort.

    Android developers interesting in creating a Ravelry app on their own can definitely contact us.

    Thursday, May 6, 2010 at 7:33 pm #
  20. You wrote: “I don’t like mixing my API actions up with my non-API actions because the logic is never the same except for the simplest methods. … or maybe I’ll see the error of my ways.”

    My money’s on the error of your ways. If your controller methods are complex enough that the log is that different, then your controllers are probably too fat.

    Sunday, May 9, 2010 at 12:26 am #
  21. Casey wrote:

    Hey Marnen,

    So far I’ve been very happy with this.

    It’s not that logic is complex. It’s just that it’s not the same. Rather than have

    if (api) # 4 lines of code else # 4 lines of code end

    ..I use separate actions. It’s been especially nice because I generate API documentation from these actions, I know that I may have to maintain backwards compatibility when it comes to these actions, and do some nice stuff with my routing and API authentication and authorization.

    My mobile app and my API isn’t a mirror image of my web app, so the (often touted in the Rails world) method of just different response types like JSON/XML/HTML for each action doesn’t make a lot of sense.

    Monday, May 10, 2010 at 10:33 am #
  22. You wrote: “It’s not that logic is complex. It’s just that it’s not the same. Rather than have

    if (api) # 4 lines of code else # 4 lines of code end

    ..I use separate actions.”

    OK…first of all, if(api) ? Really? You’re not using something like respond_to ? Why not?

    Second, I’m not sure that makes sense. If the actions are conceptually different things, of course they should be separate controller actions. But if they return the same data except that one yields an HTML page and the other a JSON packet, I don’t see what you gain from making them separate.

    “It’s been especially nice because I generate API documentation from these actions, I know that I may have to maintain backwards compatibility when it comes to these actions,”

    Yeah, API versions might throw a wrench in there…or not. I suspect routing could take care of a lot of that.

    “and do some nice stuff with my routing and API authentication and authorization.”

    How does that change how you split up your controller actions? I think the issues are probably orthogonal.

    “My mobile app and my API isn’t a mirror image of my web app, so the (often touted in the Rails world) method of just different response types like JSON/XML/HTML for each action doesn’t make a lot of sense.”

    I suspect it may make more sense than you realize. Sure, your API may not be a mirror image of your Web app, but I’d bet that many of your API calls are equivalent to your Web page calls (modulo the formatting differences mentioned above). If you make those pairs into separate controller actions, you’re probably working too hard and fighting Rails.

    Monday, May 10, 2010 at 11:15 am #
  23. Casey wrote:

    (excerpt from a response to the above)

    Short version is – Rails makes it easy to add a simple API to your app, but I didn’t find that all of the things provided met my needs for creating a well crafted, public facing, easily maintainable API. I can look at what I’ve done, consider what it will look like of the API quadruples in size, and feel really good about it. I couldn’t say the same thing about the quick and easy respond_to based REST that Rails offers.

    Monday, May 10, 2010 at 12:36 pm #
  24. Sara wrote:

    +1 for android app!!

    Friday, June 18, 2010 at 4:28 pm #
  25. Michael wrote:

    You might want to rethink the “not enough android knitters” line. Have you seen the latest numbers? All other os’s have gone down while android has surged up 4% to 13% of os’s. And that was before the samsung galaxy s. Plus we’re on the verge of a whole lot of android tablets… Just a thought.

    Sent from a Samsung Vibrant.

    Tuesday, July 27, 2010 at 10:08 pm #
  26. Stacy wrote:

    Please make an Android App! I also will volunteer to be a beta tester! (I have codeing and testing experience)

    Tuesday, September 7, 2010 at 8:49 am #
  27. Penny wrote:

    +1 for android app! Far superior OS to iPhone, lots of Andoid-using knitters!

    Tuesday, September 14, 2010 at 10:15 pm #
  28. Maria wrote:

    Please I would love an Android App very very much!

    Monday, September 20, 2010 at 5:28 am #
  29. kate wrote:

    Another vote for an android app!

    Saturday, November 6, 2010 at 11:38 am #
  30. tinfishy wrote:

    I too encourage development of an Android app. Please please!

    Monday, November 29, 2010 at 7:30 pm #
  31. Nicole wrote:

    I am nthing the requests for an Android app. If it’s an issue of not knowing how to code one or even not being interested in doing so, please say that. I think that a simple front page poll would dispel the notion that there aren’t many knitters who use Android phones.

    Monday, December 6, 2010 at 10:26 am #
  32. Insight Spinner wrote:

    Hey Android lovers. App Inventor is now out of beta and open to all users. I’m hoping to try my non-programming hand. Maybe someone here is motivated to show some love to Ravelry through that route.

    Wednesday, December 22, 2010 at 10:03 am #
  33. Rayna wrote:

    Better mobile browsing (on my DROID 2) is exactly right for me.

    An app might be nice, but I’d rather your time was spent on current & future Rav features being compatible with my phone. It’s almost perfect now, just some of the scrolling stuff are the main troubles.

    Saturday, January 1, 2011 at 10:25 am #
  34. Buffy wrote:

    I’m starting out building an API for the web app that I wrote and maintain – also in rails. Much smaller scale than Rav (for now), but what you are saying resonates. I will be following the rav api dev with interest. Thank you for sharing.

    Monday, January 10, 2011 at 3:14 pm #
  35. Tracey wrote:

    Please do NOT discount the value of developing an Android app. I think it’s very short sighted to make a blanket statement that there aren’t “enough” folks on Ravelry who use the Android OS. There are plenty of Android OS users who would be tickled pink to see a Ravelry app (I would be on it almost daily!) I haven’t seen any sort of poll on Ravelry to gather this information. Please consider taking the iPhone blinders off and include this large group of Android users!

    Thursday, February 3, 2011 at 10:37 am #
  36. Casey wrote:

    Hi Tracey,

    Did you see the link at the top of the post? We aren’t developing native apps for any devices. Here is what we are doing:

    http://www.ravelry.com/discuss/for-the-love-of-ravelry/topics/1465110#2

    Casey

    Thursday, February 3, 2011 at 12:55 pm #
  37. Alexander Staubo wrote:

    You may like my Httpdoc tool (http://github.com/origo/httpdoc), which uses a similar syntax to yours. It produces HTML from templates, but the library also comes with a simple parser for extracting a documentation data model from Ruby classes.

    Tuesday, February 22, 2011 at 8:05 pm #