Thursday, May 8, 2008

Wonderfully Simple Praise of the Hyperlink?

(Prologue: This title comes from posts written by Ben Fry and Jeremy Keith. I hope they will not mind. I find myself increasingly attracted to what they have to say on technology matters I care about.)

Here is near perfect example of a complexity problem, that I have yet to define, when comparing the integration of two APIs: Facebook and del.icio.us. One API seems to indicate what happens when you let developers define use cases and one shows what happens when you actually stop to think about how information is used by consumers. (I can say that because I write code.)

So in this case, I want to get a list of my friends. It's a dead simple request. I tell the platform I want my friends. I get back a well-formed (hopefully) document containing my data about my friends, right?

Exhibit A, The Facebook API:

facebook.friends.get

The name suggests a clean, intuitive interface...until we get into how we use the interface.

facebook.friends.get has nine parameters. Two of the parameters are separate authentication values.

The parameter call_id is documented as follows:

"The request's sequence number. Each successive call for any session must use a sequence number greater than the last. We suggest using the current time in milliseconds, such as PHP's microtime(true) function."

Which is to say that the caller is responsible for scheduling calls with the service?! Why do we have to agree on a "sequence number" in order to do business?

How about the "variable" that isn't:

string v This must be set to 1.0 to use this version of the API.

Which is to say, "Please pass me this parameter even though I already know the value."

It's a "placeholder," right? Because in "the future" we might want to leave room for specifying which version we want...per interface.

It's goes on and on. Then you tell facebook.friends.get what format you want, then whether or not you want the results wrapped in a function call so you can get around cross-domain data security, yada, yada... And don't forget to hash the URL first! I'm only talking about one endpoint here.

Ugh.

Am I wrong to be disappointed? Am I the only one who is confused? Who thinks this is unnecessary? This is the standard API-centric view of interoperability but I'm not buying it.

Now, I have little doubt there is a good reason for every parameter and for this kind of programming. I've heard every reason. I argued many of them myself...until I learned better. To gnash teeth over the legitimacy of each thing is to argue details regardless of their relevancy to the matter at hand. The matter at hand is that I am requesting my friends from the platform and I am expecting back a well-formed document as a result. That's all. From here the platform should do everything it possibly can limit the amount of additional information it requires of me. I'll grant that platform expects me to authenticate my request.

The problem with facebook.friends.get is that it is trying to serve multiple use cases through a single request, as if that is more efficient or more simple. Most of the use cases serve developers (or so they may think). Most use cases are more easily supported than the basic task I am trying to perform. Remember? It's "get my friends. " I find myself restating this important detail like a mantra in order for it to have a greater voice. Why is the service burdening the consumer with all of this minutia for a simple data call that should return a document?

Exhibit B: The del.icio.us interface for the same data:

http://del.icio.us/feeds/json/network/prestidigital

It's one simple URL. It returns well-formed data as JSON. Oh, the simplicity! Oh, the possibilities!

Detractors would no doubt point to the fact that this URL is neither authenticated nor encrypted. I would counter: that was a choice made to serve customers in this case as delicious certainly supports authenticated, encrypted interfaces that are just as easily used as /feeds/json/network. Beyond that, everything else is a decoration.

And, OK, so developers do need more options and features than can be provided through a simple URL interface. But those should be added as one or more layers on top of a layer that just provides well-formed data. I'll accept that if someone can show me: where's the layer that provides the data? It's obfuscated by the business layer. This is no doubt an artifact of the traditional three-tiered architecture (a model of which I am a proponent by the way).

On the Internet, the way in which data is located is via the URI and the way it is passed is HTTP. It's rudimentary: every container of data has a uniquely addressable identifier. Web service endpoints are URLs. We need to get developers and Internet platform providers back to this fundamental principle.

Exhibit C: Yahoo! Internet Location Platform:

http://where.yahooapis.com/v1/place/2507854


Click the URL, get back an XML document. Now THAT'S data portability; that's interoperability.



Update 11.17.09: BUMMER, this link is broken. It looks like an auth issue.