Menu

Not Quite Restful

April 27, 2005

John E. Simpson

Like you, no doubt, I've been watching all the attention paid to the REST (REpresentational State Transfer) architecture in the last couple of years. Perhaps like you, I'm not long on theory; if I can't see a technological theory in action, it's hard for me to "get" it.

Which isn't to say that REST has received no practical attention. Just here at XML.com, for example, you can find lots of articles on the theory of REST; these go all the way back at least to Paul Prescod's "Second Generation Web Services" (February 6, 2002), and on up through Joe Gregorio's "Restful Web" column series.

In this month's XML Tourist column, we'll take a look at a couple of web "services" that aren't quite formally RESTful, but demonstrate REST-like and nonetheless useful behaviors.

Google Map Hacking

One of the coolest (in fun-to-hack quotient) web applications to come along in recent months has been Google Maps. It's a pretty simple idea, really: the site visitor is presented with a basic Google-style search form, with a single input field and a search button. As with Google itself, the input field allows you to enter a wide variety of search terms — words, phrases, even simple numbers (such as ZIP codes and latitude/longitude pairs) — representing in this case anything you can come up with to describe a location or a route. The search results come back as a well-drawn map, which highlights the point(s) (and possibly a route) corresponding to your search criteria.

What's interesting about Google Maps for our purposes, though, isn't so much the razzle-dazzle look of the graphical results but rather what's behind the interface. Buried in the source code for a Google Maps results page, you'll find a bundle of XML. Here's an abbreviated version of what that XML looked like when I recently asked Google Maps to trace a route between ZIP codes 08075 (a small town in southern New Jersey) and 27109 (Winston-Salem, North Carolina):

<?xml version="1.0"?>
<page>
<title>08075 to 27109</title>
<query>08075 to 27109</query>
<request>
<url>http://maps.google.com/maps?q=08075+to+27109&amp;t=k&amp;hl=en&amp;num=10</url>
<query>08075 to 27109</query>
</request>
<center lat="38.019595" lng="-77.602560"/>
<span lat="4.012050" lng="5.295080"/>
<directions>
<source lat="40.024684" lng="-74.956128">
<address><line>NJ 08075</line></address>
</source>
<destination lat="36.100278" lng="-80.249722">
<address><line>NC 27109</line></address>
</destination>
<polyline numLevels="4" zoomFactor="32">
<points>ukhsFp}nhMz@...?kEd@</points>
<levels>B@?BB...?@@BBB</levels>
</polyline>
<segments meters="822956" seconds="30820"
distance="511&#160;#160;mi" time="8 hours 33 mins">
<segment id="seg0" pointIndex="0" meters="81" seconds="7"
distance="0.1&#160;#160;mi" time="7 secs">Head <b>southwest</b>
from <b>Moravian Ave</b>
</segment>
...
</segments>
</directions>
</page>

From a certain perspective, there's nothing remarkable about this: the XML simply carries information about the start and end points of the route, and all the points in between. Taken together, this information enables Google Maps to "draw" the route and to label it as appropriate. Where it gets truly interesting is when your imagination roams a bit, pondering what you might do with this knowledge of the structure of the embedded XML. Suppose it enables you to coax information and user-interface elements out of Google Maps (or GMaps, for short) that the application's developers haven't (yet) put there?

As of this writing, GMaps is still a moving target, a beta product: even in the short time since the service has gone public, it's undergone numerous overhauls. Features active a few months ago have been shut off, and Google is likely to respond to all the outside developer-led activity with new features at any time. Please understand the brief discussion here in that context!

One of the most striking discoveries (if that's the word) about GMaps has been what's come to be called "standalone mode." In this mode, instead of using GMaps's own user interface to generate XML which drives the map creation, you feed it an XML document of your own devising. You can also supplant GMaps's own Javascript controlling the interaction with your own.

Several sites demonstrate how to use this feature, among them these two:

  • Google Maps Standalone Mode: The chronology is a little fuzzy, so I don't know if this was the first site to demonstrate GMaps standalone mode, or just one of a crowd. It doesn't matter. Its author ("Follower") has done a great job of experimenting with, demonstrating, and providing tools to support further experiments with standalone mode. Among the latter is the myGmaps offshoot site; here you'll find two extremely useful tools for your own purposes:
    • a simple form for both generating a GMaps XML document and for viewing the resulting map; and
    • a server to which you can feed the document, via a URI of the form:
      http://mygmaps.com/show/0.0.5/?url=http://[rest of URI to document]
  • Playing with Google Maps: This site, a branch of the "Civic Mapping: Mapping Contemporary Democracy" project, seems to have taken off from the ideas and work done by Follower and gone its own route (so to speak). In particular, they're putting GMaps standalone mode maps into a harness provided by the Drupal open-source content management package. Ultimately, this could lead to applications which simplify getting people together at the same physical location, in the manner of MeetUps and other events.

One great use of GMaps — at first just a proof of concept, now on the brink of being a powerful real-world application — is Paul Rademacher's combination of GMaps and the popular Craig's List "find me a place to live" site. (It's even been noted favorably by Google itself: "Paul Rademacher's mashup of Craigslist and Google Maps blew our minds right off our shoulders. While we have no official API for Maps yet, work like this really is amazing and deserves recognition.") Not only can you locate what may be the house or apartment of your dreams, but thanks to the GMaps satellite-photo feature, you can see its neighborhood for yourself.

The Number Server

At the other end of the spectrum from Google Maps — far simpler, and far less publicly noticed — is the Number Server site. It does one thing (though in a variety of flavors), and does it well: feed it a number via the simple, one-field search form, and it tells you the results of viewing that number through the filter of numerous mathematical operations. With an extra parameter, you can even get back those results in the form of an XML document.

Here's the basic form of a Number Server query:

http://number.inelegant.org/[format/][number]

Replace [format/] with either xml or txt to deliver the results in one of those alternate ways. (Omitting it entirely returns them as a simple XHTML table.) The [number], obviously, is the number you want to learn about. (At least in its present incarnation, the Number Server accepts only integers as input. Don't include commas, either, and forget negative numbers. The maximum value accepted for input is 999,999,999,999,999.) For instance, using this URI:

http://number.inelegant.org/xml/20000529

I got back these results:

<?xml version="1.0"?>
<number number="20000529">
<sine>0.337571881486326</sine>
<cosine>0.94129975291072</cosine>
<tangent>0.358623148941105</tangent>
<squared>400021160279841</squared>
<cubed>8000634816790608035889</cubed>
<logarithm>16.8112692811685</logarithm>
<square_root>4472.1950986065</square_root>
<binary>0b1001100010010111100010001</binary>
<hexadecimal>0x1312f11</hexadecimal>
<octal>0o114227421</octal>
<md5>628d0f8238860260c46db4cb2290b202</md5>
<single_digit_sum>18</single_digit_sum>
<length>8</length>
<even_odd>Odd</even_odd>
</number>

(The md5 element, by the way, is the MD5 fingerprint of the text string comprising the number. The single_digit_sum element represents the "boiled-down" value of the number's digits when added up; in this case, for instance, 2+0+0+0+0+5+2+9 equals 18.)

If you don't want all those results returned, you can specify the one(s) you do want by adding the name(s) of the elements you are interested in to the base URI, separated by spaces if more than one. For instance:

http://number.inelegant.org/xml/20000529/md5+octal

brings back just the MD5 and octal elements of the full XML.

At one level, this seems an innocuous demonstration. The Number Server's "Submit" button invokes any of various functions (according to its author, Ben, written in OO Perl and C) to perform the mathematical operations specified or defaulted. But you can also look at this another way, which is that it represents a technique for performing those operations in an XSLT stylesheet, say, without benefit of EXSLT or other add-ons. How? By using the Number Server URI in the built-in XSLT document() function, something like this:

<xsl:value-of select="document('http://number.inelegant.org/xml/{@mydate}/md5'//md5)"/>

And this, further, implies the prospect not just of performing advanced mathematical operations in XSLT. The same technique could be employed (for instance) to provide a text-encryption facility within the body of an XSLT transformation. In this case, you might use code such as the following:

<xsl:value-of select="document('http://encryptme.org/xml/XML+Tourist'//128bit)"/>

What the hypothetical "encryption server" would return in this case would be a 128-bit encryption of the text string "XML Tourist." (And you could, of course, substitute any portion of the XSLT transformation's source tree in place of the literal text string.)

In fact, given the ingenuity and generosity of coders, whether on large project teams like the one supporting Google Maps or individuals like Follower and Ben, there's really no limit to what could be accomplished with simple XML documents, perhaps mixed with XSLT. And it wouldn't require these applications to be evaluated for their formal RESTfulness, either.