Let's call my first attempt at Where In The World the “brute force and ignorance” approach. I want to provide “where is” and “where I am” functionality over the web. Starting from first principles, web services communicate by exchanging XML documents over the web, so that's what these functions do. For now, “the web” will mean HTTP.
[Update: I've changed the schemas since this essay was published, see WITW Extensibility and Versioning for more details.]
Where Is Someone?
Give this service an identifier and it tells you the last reported location of that identifier. This service just looks and smells like an HTTP GET to me:
ought to tell you where I am. And indeed it does:
$ wget -q -O - http://norman.walsh.name/2005/02/witw/is/ndw <?xml-stylesheet type='text/xsl' href='/style/witw-is.xsl'?> <is xmlns='http://nwalsh.com/xmlns/witw-is#' date='2005-02-16T12:36:51Z'> <user userid='ndw'> <name>Norman Walsh</name> <uri>http://norman.walsh.name/</uri> <foaf:mbox_sha1sum xmlns:foaf='http://xmlns.com/foaf/0.1/'>9f5c771a25733700b2f96af4f8e6f35c9b0ad327</foaf:mbox_sha1sum> </user> <locations> <location lat='42.3382' long='-72.45' date='2005-02-15T13:31:59Z'/> </locations> <landmarks> <landmark name="The Travel Loft" lat='42.3812' long='-72.5204' dist='4.67' units='mi' uri="http://travelloft.biz/" /> </landmarks> </is>
I said that the list of “nearby landmarks” would be
optional, so that URI also supports parameters. You can add, for
?nearby=0” to turn off the list:
And if it turns out to be inconvenient in your programming API to represent the user id as path information, you can make it a parameter instead:
Where I Am
This service is a bit trickier. For one thing, I don't want miscreants out there to be able to move people around like pawns on some roughly spherical chess board. That means I need some sort of security.
The simplest thing that occurs to me is HTTP basic
authentication. Simple is good, so I'm going to use that for now. I should
https: but that requires
certificates and things that don't seem quite so simple, so I'm not going
to worry about that right now.
The rub, of course, is that in order to use basic authentication, you have to have user ids and passwords on the web server. In anticipation of the enormous popularity of this service (not!), I don't want to be maintaining that by hand. On the plus side, I already need some sort of identifier for the “where is someone” request, so I can solve both problems at the same time, I guess.
If you walk through a simple registration procedure, you too can have a user id for the WITW services and you'll also have a password to get into the WITW realm for publishing where you are.
Ok, with security out of the way, let's turn our attention back to the web service. What does the service need? It needs to know who I am and my latitude and longitude. Authentication will provide my user id, so all I really need to send is my location:
<location xmlns="http://nwalsh.com/xmlns/witw-post#"> <latlong> <lat>37.7667</lat> <long>-122.4167</long> </latlong> </location>
You do know the latitude and longitude of every city and place on earth, don't you? You don't? Uhm, ok, let's give you the option of specifying your location by landmark instead:
<location xmlns="http://nwalsh.com/xmlns/witw-post#"> <landmark> <name>Logon International Airport</name> </landmark> </location>
Better? Maybe. Now you have to know what landmarks
the service knows about, but I've already said we'll worry about that later.
In short, you can update your location by doing an HTTP POST to
http://norman.walsh.name/2005/02/witw/ami/now sending a document
that conforms to
XSD, if you prefer):
wget -q -O - --http-user ndw --http-passwd PASSWORD --post-file /tmp/loc.xml \ http://norman.walsh.name/2005/02/witw/ami/now <ami xmlns='http://nwalsh.com/xmlns/witw-ami#' date='2005-02-16T13:03:55Z'> <user userid='ndw'/> <location date='2005-02-16T13:03:55Z' lat='42.3382' long='-72.45'/> </ami>
Now I have two addresses that the world can interact with to perform actions. I think those are Web Services, at least in a broad sense. But I'm troubled by the lack of symmetry. You can GET from one and POST to the other. I don't know if it's proper web services architecture or not, but I decided to support both operations on both addresses.
And if you do a simple GET on the
http://norman.walsh.name/2005/02/witw/ami/now address, you'll
get back an HTML form that you can use to do the POST, which seems
I think I've got a couple of web services now. I wouldn't claim they've really been “tested” exactly, but I've used them once or twice. The schemas a pretty ugly, I should probably clean those up a bit. And there are no WSDL files or other machine readable descriptions of the APIs, I should probably work on that.
In the meantime, comments most welcome. Several people commented on the first essay offering suggestions for extensions. I might get to those eventually, but baby steps first, I think. Besides, adding them later will let me experience the joys of schema evolution and versioning.