b-log – betriebsraum weblog

Software Development, Human-Computer Interaction, Projects…

Why Facebook App Development is Seriously Flawed

August 24, 2011

Recently, the facebook API has been voted »Worst API« in a developer survey. Bad news first: It really is the worst API (or at least the worst API that we have worked with). Good news: It would be quite straightforward for facebook to drastically improve the overall app development experience by working on at least one specific area (see end of this article).

This post describes some of the difficulties we had while developing our social betting app Betista and – if you haven’t developed any
facebook apps yet – will give you a few hints on what you should watch out for.

Designing a good development platform is known to be extremely difficult. It’s even more difficult for a platform as complex as
facebook. You need to consider all kinds of different use cases, you need to provide lots of examples and documentation, you must not break anything at any time, be backwards-compatible, be consistent etc. The more developers are dependent on your platform the trickier it gets. However, and this is the first major point of criticism, there is no good excuse offering incomplete, scattered and faulty documentation such as facebook does.

Documentation and Code Examples
The facebook documentation really is a joke. The whole documentation system consists of a mix of blog post-like pages, some tables outlining API methods, forum posts and comments and other content from their developer blog. It’s a total mess. If you haven’t used this system long enough so that you have internalized where to look something up, you will have a hard time. Some important points are only briefly mentioned in a post on their development blog but not part of the official docs.

The examples they provide are not only incomplete (or non-existent because often no examples are given at all) but also promote very
sloppy, ugly coding style. Moreover, some of the information is just plain wrong. Just an example: In their JavaScript SDK, there is a method to get the measurement data of the canvas your app is running in. The method returns width and height as strings. This is, of course, nonsense and causes errors in your code when used in calculations. One could live with it if it was stated in the docs that the method returns this data as strings but it says that it returns integers. While this isn’t the end of the world, it still eats up your time until you have figured out what’s going on. This hasn’t been corrected by the time of this writing, even though one user states the error in the comments.

Authentication
Facebook uses the open authentication standard (OAuth 2.0). Unfortunately, they haven’t implemented refresh tokens even though this is (an important) part of the official specification. Why is it important? To make certain API calls, you need to obtain a valid access token first. On facebook, this token is short-lived and expires after two hours or so. When the token has expired, the API returns an error. So what facebook suggests (in some blog post…somewhere) is that you should catch this API error and then re-run the authentication process, i.e. you have to redirect to the authentication endpoint and then back to your app. If this happens during an AJAX call, it’s very hard to handle the situation in a way that doesn’t disrupt the user’s current action. Using refresh tokens, this could gracefully be handled in the background on the server – and yes, it looks like some other APIs do indeed offer refresh tokens…

API Response Data and Parsing
In theory, all is good if your API responds with JSON data and even better if it does so consistently. Not so on facebook. Most parts of the API return proper JSON, some other parts return key-value pairs or only plain values. Sometimes the actual JSON data is wrapped in a data property, sometimes it isn’t. Add in processing of batch requests and your facebook api class quickly gets full of parsing logic to handle all of those different cases. Sometimes the API returns JSON data that doesn’t make sense at all. For example, in a batch call for sending app requests, the returned request IDs are wrapped in quotes twice (so four double-quotes in the JSON result). Even more response parsing logic!

The Canvas and the iframe
Facebook apps mostly run in an iframe which can cause all sorts of problems and complicate development. For example, there are security issues with cookies in Internet Explorer when content in an iframe is loaded from a different domain (which is the case with facebook apps). Since access to the content embedding the iframe is restricted (which is probably why facebook uses iframes in the first place), they provide some methods to manipulate and query the outer content via their JavaScript SDK. Examples are setting the scrolling position of the browser window or setting the size of the canvas (the area of your app). First, this further complicates development since you now have to deal with things that are usually done automatically by the browser. Second, it exposes additional cross-browser issues (try centering a popup on a canvas with variable content so that it works on mobile devices). Third, the facebook canvas is buggy and resizing to dynamically generated page content just doesn’t work as it should. And, if you rely on the automatic resizing functionality (which is buggy), you also have to pay some performance penalties.

JavaScript SDK and Social Plugins
Facebook has a new JavaScript SDK that deprecates their old JS SDK and FBML (facebook markup language) style tags. The new SDK is able to render only a subset of the old FBML components as XFBML (it remains unclear what the exact difference between FBML and XFBML is). Of course, some of the most useful components, such as a friend-selector, are not yet ported over to the new SDK which basically means that there is no friend-selector component since it’s officially not recommended to continue using FBML. Consequently, if you need a UI to select friends, you have to code your own (this is not as easy as it sounds) or rely on third-party plugins (mostly some jQuery spaghetti hackery). Both very dissatisfying. Even for components where there is an XFBML version, those are dumbed-down, ready-made plugins with little options for customization. On Betista, for example, we use a social plugin for comments but as we don’t have access to something like a component API, we can currently only use this plugin for public bets but not for private bets.

Social Channels and App Requests
Social Channels is yet another concept for integration of social features into an app (this is one of many different aspects that facebook labels an »advanced concept« in their docs). One social channel is »requests«, i.e. the possibility to invite friends and engage them with your app via notifications. When you have finally understood the difference between »app-generated« and »user generated« requests and what their implications are, development annoyances go on: One can only send user-generated app requests (these are the more useful ones that also appear as facebook notifications) using facebook’s own UI dialog. But this component doesn’t have a very useful API. For instance, it doesn’t allow you to get the user IDs of selected friends, it just gives you request IDs. To get the user IDs (which you might want to store in your database) you need additional batch calls to fetch the full request objects. It’s hard to come up with a good reason why there is no simple method or callback or event that lets you get the IDs of what you have just selected in this dialog. Further, since the requests are immediately sent when you press the send-button, you have to code your app logic in a way so that it can handle situations where app requests are already sent but couldn’t be stored in your own database yet. This can lead to code complexity that could be easily avoided if such components provided proper APIs.

Example: On Betista, you can create private bets and invite friends to participate. If you press the button to create a new bet, it is already stored in the database although you couldn’t invite any friends yet. Ideally, you would select the friends before creating the bet and ideally you could also change your selection again but facebook won’t let you do that. So, the bet is created and only then can you display the dialog to send app requests. At this stage, the users have already received notifications that they had been invited. However, since facebook doesn’t give you the user IDs immediately, you have to first fetch the full request objects before you can store the IDs in your database and thus know who is allowed to view the bet. To support situations where a user would immediately view the bet via a notification, you have to call again the graph API, check the user’s outstanding app requests and only save them if they haven’t already been saved before and so on… While this is not buggy, it is just unnecessary code for a straightforward use case like »send app request to user«. Buggy again, however, is some other behaviour related to notifications (see next section).

Bookmarks and Notifications
Once you have managed to send app requests, users get counters and notifications in their profile to tell them that there’s something to do in the app. Then, when a user clicks the app bookmark in their profile or a specific notification, facebook appends some variables to the app URL so that you know where the user came from. The problem is that those variables aren’t sometimes correctly set. That means that you have to call the API (to check for outstanding app requests, for instance) even though you shouldn’t have to (or vice versa).

To sum up…
Given that facebook is one of the most complex platforms and employs some very bright developer minds, the tools they provide for app development seem surprisingly incomplete, buggy and inconsistent. This is even more surprising since they repeatedly blogged something about »operation developer love«. For app developers of reasonably complex apps that depend on different parts of their APIs, SDKs and plugins, this often means hours of wasted time and writing unnecessary code.

Improvements?
Criticizing is always easy, of course, and there’s no doubt that with an organization as big as facebook, there are certainly good (technical) reasons why some things are as they are. A developer could live with some of those annoyances if they were at least pointed out in the docs (and not just mentioned somewhere in the comments or a forum post). The single most important and probably most worthwhile point for facebook to improve the overall development experience is to provide good documentation. Documentation that is well organised, contains lots of high-quality, well commented code examples and points out any pitfalls and existing issues. Companies such as Google or Yahoo show that this is definitely possible. So why doesn’t facebook give us more of their promised »developer love«?

Filed under: JavaScript, Ruby / Rails, Software Development

Add a comment

Follow comments to this post by subscribing to the comment feed.