TV version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer


Weblog Entry

The Web Really is an API

November 29, 2004

Every so often I’m reminded of how the simplicity of the web is belying of the underlying power.

Generally speaking, the web provides a simple user interface that has the ability to power increasingly complex back-end interactions. The more I delve into the nuts and bolts of how things like HTTP work, the more I realize that the implicit transparency of it all creates prime opportunities for even know-nothing coders like myself to build more and more sophisticated interfaces and applications.

Once the data hits the server it’s mostly smoke and mirrors to me. But the data that hits the client side is quite transparent, and easy to tweak at will. The web is built on View Source, Open Source, and transparent URIs.

For example, the more I use Movable Type, the more I end up routing around the scripts and code that are provided out of the box. I’m creating my own interfaces for common tasks, customizing for my own preferences and improving where I see fit.

Case in point, the tweaked search page on this site which uses PHP to move beyond the limitations of MT’s built-in templating (made possible thanks to the HTTP get method), or the tweaked comment preview pages which tap directly in to the common templates used elsewhere throughout this site, and allow PHP usage on those pages (something you don’t get out of the box).

Article Buttons

Now thanks to View Source and the ability to trigger actions via a hyperlink, I’ve been able to litter this site with hooks back in to the MT interface to perform common actions, from the pages on which I wish to perform them.

For example, on every page what I now see is a list of actions running down the sidebar that allows me to do things like jump directly into the comment editing and clear the activity log. When I visit an individual article page, I get a set of buttons that allows me to perform actions like edit the original article or rebuild it (or even outright delete it if I’m so inclined).

I see them because I have a cookie set on my hard drive:

setcookie ('aCookie', 'aValue', time()+31536000, '/');

You don’t see them because the PHP that checks for that cookie selectively hides them from you:

if ($HTTP_COOKIE_VARS["aCookie"] == 'aValue') {
  // here's where the good stuff goes
}

This is nothing revolutionary, and WordPress and others have had this type of functionality for ages. It’s not the final result that’s important here, it’s that a non-coder like myself could whip this up in a matter of a few hours (including button creation time) simply by observing output and modifying it accordingly.

The MT interface works based on simple hyperlinks, each performing an action with data being passed to and fro via querystrings. I grabbed the relevant links straight from the interface. There was nothing saying I couldn’t just right-click -> Copy Link to Clipboard and then use that URI on another page, which was exactly what I did. In cases where variable data was being passed via querystring, it was a simple matter of replacing things like Entry IDs with their programmatic equivalent.

The importance of this isn’t to say hooray me for hacking up Movable Type (although I am rather pleased with how far I’ve been able to extend it). Rather, the concept of observing the data being passed to the client side, and then manipulating it and sending custom data back to the server in a form it expects, is basically a (poorly documented) front end API in and of itself.

An API, or Application Program Interface, is a set of routines that form the basic building blocks of an application. Web sites have been making use of APIs for years, e.g. Google and Amazon.

Theoretically it’s not even necessary to see what’s happening inside the server. A web browser exposes all the information passed to it, and viewing the source nets server variable names. It’s even easier when the HTTP get method is used, since the variables are right there in the URI.

All this transparency means these pieces of data can be used elsewhere. With a bit of trial and error, and assuming there’s nothing in the script specifically blocking the practice, there’s no reason why an entirely new front-end interface couldn’t be built for any number of web-based applications and services.

But as for what the server does after receiving the data though, well, that’s what a more formal API is for.

(The title of this article is, of course, a reference to Joel Spolsky’s infamous “How Microsoft Lost the API War”.)


Reader Comments

Hans says:
November 29, 02h

My god, that’s brilliant, yet so simple!
I might as well go do that right now with Textpattern…
Marvelous! So simple…

This is the umpteenth time you’ve though of something I’ve never even hear of before, but it’s been right under my nose for so long.

Thanks!

November 29, 02h

I do like the sexiness of this usage since you include the functionality you need without having to request updates from the software originators. I recently signed up on Technorati and they encourage you to bookmark a particular link that, when accessed, automatically tells Technorati that your weblog has been updated. Obviously, this uses the GET method to pass in the info. It’s only a matter of including an iframe on the content submission form of your blog software to do this one step for you without having to remember to go to the link yourself.

Ah, the joys of the web… it truly IS an API.

November 29, 02h

P.S. I only just now thought of adding that iframe to the “content posted” page of my blog as I was writing my response. Thus, as Hans mentioned, it was right under my nose… you just brought it up to eyelevel.

November 29, 02h

Funny… When you hover over the word API, the tooltip says “Application Interface” - how unhelpful, as if somebody who doens’t know what API means would know what Application Interface does mean.

seth says:
November 29, 03h

Great idea, Dave. I may implement this tonight!

As soon as my site becomes wildly popular (not) I might even have a reason to use the added functionality.

Dave S. says:
November 29, 03h

Well, thanks Hans, but I definitely can’t take credit for the idea itself. As I reference in the article, I cribbed the basic idea from WordPress, and I’m pretty sure before that at least one product from UserLand offered the same functionality.

…but I made some buttons. Everyone loves buttons.

Pascal says:
November 29, 03h

>…but I made some buttons. Everyone loves buttons.

it’s the looks that kill, baby. it’s in the looks…

Damion says:
November 29, 04h

My brain took leaps and realized how much more important CSS is for web applications, in regards to the web being an API. How much easier will it be to parse data into applications without having to work around alot of formatting tags. For example looking at the source of this comments page, I could imagine a XUL frontend that understood the comments and such, very easily. Without full CSS, you would have to come up with a new parser whenever a new design came along.

Just great… now I can’t be lazy with my redesign.

Anil says:
November 29, 04h

I’m pretty sure Blogger had this sort of functionality back in the day, too. And there have been some documented efforts to do this with MT, everything ranging from wikifying pages to front-end editing:

http://www.brain-dump.com/2003/08/frontend_editing_for_movabletype/

And I think our own Brenna and Shelley documented this even before that:

http://www.thegirliematters.com/tips/archives/0210/edit_link_for_entries_with_php.php

But the core point, that URLs are eminently hackable, and that this sort of hackability can yield some really fun results, is one of those ideas that I keep rediscovering and getting excited about again and again.

The most interesting point to me is that, the same day you’ve posted about this, Arvind posted about another way of hacking MT’s URLs. Maybe we should take the time to document these options. :)

http://www.movalog.com/archives/code-snippets/reset-templates.php

Indranil says:
November 29, 10h

Greatly implemented. Really nice.
You should congratulate yourself by making a couple of more buttons. ;)

November 30, 01h

I wish we could see a larger screenshot of those buttons. ;-)

This is a great idea, though. I have been seeing all of the new comment editing links in the MT3 comment emails and have been thinking of doing something with them. Your ideas here are certainly going to help with my final solution.

November 30, 02h

Joel Spolsky touches on the web as an API in his larger article on what amounts to the future of Microsoft. An interesting read, though it’s pretty long.

http://www.joelonsoftware.com/articles/APIWar.html

13
Mike says:
November 30, 02h

Big downside with this approach: Maintenance. In a few months, try to make some changes and see if you can make head or tail of your own code.

Or worse, upgrade to the next version of MT and fix what breaks. Repeat for each new release.

Eugene says:
November 30, 07h

Just to point out one thing: you’re possibly breaking the safe-idempotency of the GET method of HTTP. This basically means that if you GET a resource specified by a URL, it shouldn’t change the state of the web server (such as deleting the resource). The POST method is more appropriate for those kinds of stuff (or even DELETE or PUT).

See http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html for more details.

Of course, there’s no way to specify that clicking on links uses another method other than GET. Only HTML forms AFAIK can specify the method. So in practice, GET is often used, even though it is incorrect.

November 30, 07h

Eugene wrote:

“This basically means that if you GET a resource specified by a URL, it shouldn’t change the state of the web server (such as deleting the resource).”

More precisely, if you GET a certain resource twice in a row, the second GET should have *exactly* the same effect as if you just did a single GET.

Let’s please not mess with the HTTP Spec by breaking Idempotency.

“The POST method is more appropriate for those kinds of stuff (or even DELETE or PUT).”

And there’s no reason Dave’s PHP script couldn’t insert a little HTML form, which used POST (say) to achieve whatever non-Idempotent action he wished to achieve.

December 01, 09h

Back when I used CuteNews (a PHP script for posting updates on a web site), I completely rewrote a lot of the frontend, but kept it a local GUI for adminning the site updates.

On another site I wrote, when I or another person is logged in, there’re hooks on each page to the admin services. Quite useful indeed.

The thing I realized when writing my own updates script for the first site is that every admin action needs to make sure it’s after a cookie-check, so no can somehow use the controls by finding out the URLs. Now I just need to find a way to improve the cookie, so one can’t use it were they to somehow get my cookie - I’m thinking a password/IP md5 hash within the cookie.

I wonder how maintainers of MT, CuteNews, etc. would feel if someone released an alternate, more usable, admin center to their script…

Note: When I put two - in a row, the Preview doesn’t work. This is in Firefox 1.0 on Linux, and doing a View Source shows that the comments with the post in it, and the double - prevents the comment from closing properly, resulting in an unusable Preview page.

December 01, 11h

Really nice. Thanks for the great idea! :)

18
Andrew says:
December 06, 12h

Thats $_COOKIE[“aCookie”] now ;)

joestump says:
December 08, 08h

BTW, the $HTTP_*_VAR’s are deprecated. You should be using the following vars: $_POST, $_GET, $_COOKIE, $_SERVER, $_SESSION. You should also check out turning off registered globals.

dclal says:
December 11, 07h

To keep things simpler in the individual archive code, you can replace some of the code with MT tags. There is less customization this way, and you can use the code on blogs with an id other than 1.

1. change “http://www.yoursite.com/mt/” to “<MTCGIPath>”

2. change “blog_id=1” to “blog_id=<MTBlogID>”

Of course, remove the quotes.

Thanks for the code Dave, it works brilliantly.