At the Forge - Facebook
Last month, I described a growing trend in the world of Web/database development. No longer are developers content to create interesting new applications for people to consume. Rather, more and more companies are looking to create service-based platforms, upon which other developers can create new and interesting applications.
For example, many of us think of eBay as a Web site that handles on-line auctions. And it's true; at the end of the day, what pays the bills at eBay is the fact that many people are buying and selling things. But eBay has been especially successful because it offers not a particular application, but rather an infrastructure upon which buyers and sellers can create their own applications. Many of those applications might be invisible to the average user, but they exist nonetheless. There already are many software packages that help vendors price, track and sell their wares, and there are similar packages designed for buyers.
It's pretty easy to differentiate between an application and a platform. The former might have a great deal of functionality, but changes and additions all come from a central group of developers. By contrast, a platform includes software libraries and/or APIs designed to make it easy for developers to expand and modify the core functionality independently. As a platform grows in popularity and developers make use of the API, a small software ecosystem takes root, making it harder to compete with the ecosystem, because so many people have a vested interest in keeping it going.
One of the biggest platform successes of the last few years is Facebook. Facebook originally was meant to be a small, Web-based version of the book that newcomers to Harvard (and MIT, for that matter) are given when they first arrive. Facebook quickly took off, offering a growing amount of functionality, and expanded to students at other universities. Facebook then invited everyone—students and nonstudents alike—to become members. Then, in mid-2007, the Facebook team unveiled F8, the Facebook development platform and API. Now there are tens of thousands of Facebook developers, and although many of them are creating trivial or silly applications, some are creating interesting and profitable ones. Moreover, many people now prefer Facebook to rivals, such as LinkedIn, partly because their friends are on Facebook, but also because there is a large library of Facebook applications they can install and use.
To Web developers, of course, Facebook provides not only a library of applications that we can use, but also an infrastructure on which we can create our own applications. This month, let's dip our toes in the waters of Facebook application development, create our own simple application and see how it can hook into Facebook.
If you have been developing Web applications for a while, you might wonder how it is that Facebook allows people to add their own code to a running Web site. Do you upload your code to a virtual server? Do you run it through a Web service? Do you write it using a macro language within the Facebook system?
The answer turns out to be simpler than any of these possibilities. You run your Web application on your own server, write it in whatever programming language you choose and include whatever functionality you want. When someone invokes your application via Facebook, the Facebook server then makes a request to your Web application. The output from your application is passed along to Facebook, which then integrates it into the page and finally sends the output to the user's browser. In other words, you can think of Facebook as a proxy HTTP server, one that you can configure to allow people to visit your site.
But, of course, things are a bit more complicated than that. When it is invoked by a user, your Web application has access to information about that user and about that user's Facebook friends and networks. Thus, it's possible that Facebook will invoke your application on behalf of a user—and that before it returns any output, your application will send a number of queries to Facebook to learn more about the current user. This back and forth is surprisingly fast, at least on the Facebook end, but it does mean you need to think about what information you really want to request from Facebook, if you want to ensure that your application runs at top speed.
The first step in creating a Facebook application is to add the Developer application by going to facebook.com/developers . (When you create your own application, people then will have to add it in a similar way.)
You will be asked if you want to add the Developer application. Every application on Facebook has a unique name; I suspect that over time, people will hoard application names, just as they have done with domain names. Notice that you need to agree to add an application explicitly, and that Facebook provides you with a number of options to protect your privacy. So, you can allow (or forbid) the application to access information about you, to put a link in your navigation list or even to publish stories in the “feed” on your home page. This last item is particularly important; when checked, it allows applications to write to your personal feed, which then is picked up and displayed on your friends' home pages.
Once you have added the Developer application, you now can create your own applications. Note that only those Facebook users who want to create new applications need to add the Developer application; if you only want to use applications, there isn't really any need for it.
Now, it's time to create a new application. If you have just added Developer, you will be presented with a link asking if you want to create your first application. If you already have added Developer, go to the Developer home page (facebook.com/developers) and click on see my apps. In either case, you'll be given a chance to create a new application. Each developer can create almost any number of applications, and it is free of charge—so don't think that you need to skimp on the number of applications you create.
To create an application, click on the link that says “create one”, or if you already have an application, click “apply for another key”. The simplest possible application has nothing more than a unique name. But, in general, you should fill in a number of the optional fields associated with an application. Thus, although you could create an application by entering its name and checking the “I have read the terms” box, you probably want more. So, click the optional fields link, and enter the following information:
The support e-mail address should be yours, at least for the time being.
The “callback URL” should be a URL on your server that is connected to a Web application framework. In our case, we're going to use a development system for Ruby on Rails for our server application. Thus, the callback URL will be http://atf.lerner.co.il:3000/hello/facebook.
The “canvas page URL” should be where you enter the application's unique name again. I used rmlljatf for mine, because this is my Facebook application for my column (At the Forge) in Linux Journal. You will need to choose a different name.
You can ignore a number of the settings, such as whether you should use FBML (the Facebook Markup Language, a superset of HTML) or iframes, and whether you want a Web or desktop application (in this case, we want the former).
We do want people to be able to add our application on Facebook. However, we don't want the new application to be displayed in our feed, and we also want to restrict the application to developers who are working on it. So, although we will click the yes check box that allows people to add the application, we also should click the developer mode check box farther down and the private installation check box below that.
When you finish filling out this form, press Submit. If the form contains no errors, you will be told that your application was created successfully. Moreover, your new application now will be on your developer page. Among other things, your application has an API key and a secret. These are 32-character strings that Facebook uses to ensure that your application and the Facebook server are allowed to communicate.
Facebook now is ready to communicate with our Web application—we had better create one! As I mentioned previously, I'm using Ruby on Rails to create a simple Web application that speaks with Facebook.
Now, I could do all the hard work myself. I could read the Facebook documentation, learn the APIs and debug things. Or, I could benefit from some amazing work that others have done, and think about my application, rather than communicate with Facebook.
If you are using Ruby on Rails, you can do this by installing a Ruby gem (that is, a prepackaged bundle of code and documentation):
gem install rfacebook
The rfacebook gem includes everything you need to speak with the Facebook server from an application. But, it doesn't include some of the glue that a Rails application needs. For that, you need to install a Rails plugin. So first, let's create our Rails application, specifying PostgreSQL as our database:
rails -d postgresql rmlljatf
After Rails creates all the files it needs, we now can install the rfacebook_on_rails plugin:
cd rmlljatf script/plugin install svn://rubyforge.org/var/svn/rfacebook/plugins/rfacebook_on_rails
Note that in order for this to work, you need to have a Subversion client (svn-client) installed. You also will discover, as I did, that if you don't have the Ruby SSL libraries installed, RFacebook will fail mysteriously. On an Ubuntu machine, such as I'm running, I installed that by typing:
apt-get install libopenssl-ruby
With all these things in place, we now can use the plugin to configure Facebook for our system:
rake facebook:setup
Among other things, this creates a configuration file for our Facebook application in config/facebook.yml. As a very explicit note indicates during the execution of rake facebook:setup, we need to open and edit this file in order for things to work. When you open it, you'll see that you need to enter your API key and secret (from the Facebook Developer page on the Web). Where it says yourAppName next to canvas_path, enter your application name. In my case, it's rmlljatf. And, where it says callback_path, replace it with the URL you expect to use for the Facebook application on your server. In my case, that's just /hello/facebook. (This should be a relative URL.)
Let's create a controller for our application:
./script/generate controller hello
Then, remove the file public/index.rhtml.
Finally, create a simple method in our hello controller:
def index render :text => "hello" end
Sure enough, when I point my browser to http://atf.lerner.co.il:3000/hello the controller (hello) is invoked, as is the default action for that controller (index). And, I see “hello” in plain text in my browser. Yay!
Let's write a tiny bit more code to get things ready. First, let's define a new method in our hello controller:
def facebook end
Notice that we haven't defined anything in the method, other than that it exists. Next, we create a facebook.rhtml file in app/views/hello:
<p>Hello, FacebookWorld!</p>
We can see the results at http://atf.lerner.co.il:3000/hello/facebook, which displays:
Hello, FacebookWorld!
Experienced coders know that looking through log files is a great way to keep track of what is happening. Rails includes a log file for each environment, giving you separate logs for the development and production environments, in case they're installed in the same directory on the same computer.
If I look at the development log (logs/development.log) after my invocation of the index method, I see the following at the bottom:
Processing HelloController#index (for 84.110.255.110 at 2007-09-12 08:26:08) [GET] Session ID: ef0e25ea44f91f3c900f54c4bca93506 Parameters: {"action"=>"index", "controller"=>"hello"} Completed in 0.00339 (295 reqs/sec) | Rendering: 0.00016 (4%) | 200 OK [http://atf.lerner.co.il/]
None of that should surprise us, and it even should make us happy. But, if I look right above that, I see some log file messages that are coming from the RFacebook plugin:
** RFACEBOOK INFO: It looks like you don't have memcache-client, so MemCacheStore was not extended ** RFACEBOOK INFO: using default Rails sessions (since we didn't find an fb_sig_session_key in the environment)
It looks like even without explicitly asking for RFacebook to do anything, it already has started to look around and act. The first message has to do with memcached; although it might be useful for certain distributed applications, we don't need it for right now. The second note indicates that our method was invoked directly, rather than via Facebook, so there wasn't any Facebook session information to retrieve. As a result, we'll use regular Rails sessions, rather than Facebook sessions.
How can we invoke our application via Facebook? The first thing to do is add the application. Go to the developer page (facebook.com/developers), and click on the name of the application (rmlljatf). On the right side of the page, there should be a big blue button marked Add application. Click that button, click the similar button on the next page, and the rmlljatf application will be installed.
Now, I can point my browser to http://apps.facebook.com/rmlljatf, and what do I see? Yes, you guessed it—a cute little message, saying:
Hello, FacebookWorld!
We managed to point our browser to Facebook, which invoked the application on our server, which returned results that were then displayed inside of the Facebook page. Not bad, right?
This month, we saw how we can basically connect a Web application on our server with Facebook, displaying the output inside a Facebook page. Next month, we'll look at how our Web application can access information from Facebook, interacting with the Facebook database in a number of different ways.
Resources
Facebook: www.facebook.com
Facebook Developer Documentation: developers.facebook.com/documentation.php?v=1.0
rfacebook: rfacebook.rubyforge.org
Reuven M. Lerner, a longtime Web/database developer and consultant, is a PhD candidate in learning sciences at Northwestern University, studying on-line learning communities. He recently returned (with his wife and three children) to their home in Modi'in, Israel, after four years in the Chicago area.