Pushrod

Old dogs, new tricks

Archive for the ‘observers’ Category

Facebook, hyperactive APIs and lightweight libraries

with one comment

Probably the single biggest annoyances with writing (and running) a Facebook app is the remorseless changing of the API, to the extent that you begin to wonder sometimes whether it’s worth it.

For those who’ve not yet made the plunge, we’re not talking about minor tweaks, or once-in-a blue-moon essential maintainence that’s introduced over several months.

Oh no. With the Facebook API, you get major, app-breaking changes that are introduced with just a few weeks’ notice. The latest one got people so excited, it even made TechMeme’s front page:

TechMeme Facebook API change

Recent highlights include the deprecation of the whole method of sending invitations to other users, which is a central part of most applications, yet was scheduled to happen in “around 2-3 weeks” after the announcement.

So what’s a person to do? Duck out of the whole Facebook thing? Hope that OpenSocial solves all your problems, providing a standardized, flexible, and stable interface to a who bundle of social networks? Don’t hold your breath — it’s only at version 0.5 at the moment – and they are quite open that it’s going to change, and change rapidly.

The other option is to hang on and ride out the bumps, which is what I’m doing with Autopendium, the old-car community website I run, which gets a steady stream of new users thanks to its Facebook app, which keeps your profile and feed up-to-date with your old cars.

The most recent change I had to sort out was the introduction of templatized (ugh!) feed notifications, which will be replacing feed.publishActionOfUser in time.

In many respects, this was an easy change, certainly much easier than changing the whole invite procedure, which required rewriting the controller actions both for showing friends to invite, and sending the invitations (at least it would have been, if I’d carefully read the API).

The Autopendium app updates users feed whenever they add a new vehicle, or add a running report entry to one of their existing vehicles, using my favourite method of observers, specifically using a general FacebookObserver class, and my lightweight facebook library.

class FacebookObserver < ActiveRecord::Observer   
  observe Vehicle, Post
    def after_create(obj)
      update_facebook_info(obj)
   end  

  private   
  def update_facebook_info(obj)     
    user = obj.user
    return true unless @facebook = user.facebook # instantiate facebook session object from user
    update_profile_box_of(user) # update their profile
    publish_action_about(obj) # and their newsfeed too
  end

  ...    

  def  publish_action_about(obj)
     title = "<fb:userlink uid='#{@facebook.user}'/> added a new vehicle on Autopendium"
     body = "#{obj.title}: #{obj.description[0..80]}..."
     @facebook.fb_feed_publish_action_of_user(:title => title, :body => body)
   end
 end

To change this to the new feed.publishTemplatizedAction you only need to change a couple of line, specifically:

  def  publish_action_about(obj)
     title_template = "{actor} added a new vehicle on Autopendium"
     body_general = "#{obj.title}: #{obj.description[0..80]}..."
     @facebook.fb_feed_publish_action_of_user(:title_template => title_template, 
        :body_general => body_general, :actor_id =&gt @facebook.user)
   end

What makes this such a breeze is having all the Facebook updating done in an observer, rather than in the various controllers, and, I think, the fact that the Facebook library is so transparent, meaning it’s easy to change, add or remove methods as Facebook does.

There is a downside, however, and it’s that fairly eloquently explained by Chad Fowler, when discussing his Facebook library, Facebooker. In brief, “If Facebooker didn’t hide the implementation details of the XML API from its end-users, a change in the XML API would require every application which uses Facebooker to change.”

Essentially, the great thing about it is that the app (and the developer) doesn’t need to worry about Facebook changing its API, because that’s the library’s job. Which is great. We like things that make our life easier. Except…

Except that when something’s changing as much and as fast as the Facebook API, I think it falls down. I think there are three main problems with this ‘black box’ approach:

  1. It assumes the black box is updated as frequently as the API. Now in the case of Chad’s library, that seems to be the case (it’s had well over 100 commits and even has support for templatized actions). However, I got myself into trouble with Ruby/Amazon, which is no longer supported and is stuck at version 3 of Amazon’s API (and thus dead from early next year). I moved to the much more straightforward amazon-ecs, which, ironically, I have abstracted somewhat.
  2. It assumes the API changes can be fully handled by the black box without you having to be aware of them — and I just don’t think that’s the case with Facebook’s API. Even with something as well written and maintained as Facebooker, you still have to subscribe to Facebook’s developer news, and change your code to take account of it, particularly with something like notifications.sendRequest, or feed.publishTemplatizedAction because they force you to change your app or force Facebooker to change its API.
  3. It reduces the time you have to make those changes (again this is not so much of a problem with something like Facebooker, although I’m not sure it’s been formerly released yet) while you wait for the library to catch up, and adds opacity to the process.

So, for me (a relative newbie), a lightweight Facebook library seems the way to go, at least until the API settles down a bit, (and I tend to think it’s not dissimilar to some of the moves Rails has made in moving to 2.0).

Advertisements

Written by ctagg

November 21, 2007 at 9:11 pm