<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet href="/style/browser.xsl" type="text/xsl"?>
<essay xmlns="http://docbook.org/ns/docbook"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
       xmlns:dc='http://purl.org/dc/elements/1.1/'
       xmlns:dcterms="http://purl.org/dc/terms/"
       xmlns:gal='http://norman.walsh.name/rdf/gallery#'
       xml:lang="en"
       version='pto'>
<info>
<title>WITW Part I: Brute Force and Ignorance</title>
<volumenum>8</volumenum>
<issuenum>24</issuenum>
<pubdate>2005-02-16T09:16:29-05:00</pubdate>
<date>$Date: 2005-09-11 10:27:02 -0400 (Sun, 11 Sep 2005) $</date>
<author><personname>
<firstname>Norman</firstname><surname>Walsh</surname>
</personname></author>
<copyright><year>2005</year><holder>Norman Walsh</holder></copyright>
<abstract>
<para>Simply exchanging XML documents over HTTP.</para>
</abstract>
</info>

<para xml:id='p1'>Let's call my first attempt at 
<link xlink:href="../15/ws-wtf">Where In The World</link>
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.
</para>

<para xml:id="update">[Update: I've changed the schemas since this
essay was published, see <link xlink:href="../21/witw-versioning">WITW
Extensibility and Versioning</link> for more details.]</para>

<section xml:id="whereis">
<title>Where Is Someone?</title>

<para xml:id='p2'>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:</para>

<para xml:id="p2b"><command>wget</command> <link xlink:href="http://norman.walsh.name/2005/02/witw/is/ndw">http://norman.walsh.name/2005/02/witw/is/ndw</link></para>

<para xml:id="p3c">ought to tell you where I am. And indeed it
does:</para>

<programlisting><![CDATA[$ 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>]]></programlisting>

<para xml:id='p3'>The replies are XML documents that conform to
<link xlink:href="examples/is-reply.rnc">this schema</link>
(in 
<link xlink:href="examples/is-reply.xsd">XSD</link>, if you prefer).</para>

<para xml:id='p4'>I said that the list of “nearby landmarks” would be
optional, so that URI also supports parameters. You can add, for
example, “<code>?nearby=0</code>” to turn off the list:</para>

<informalexample>
<para xml:id="p5"><link xlink:href="http://norman.walsh.name/2005/02/witw/is/ndw?nearby=0">http://norman.walsh.name/2005/02/witw/is/ndw?nearby=0</link></para>
</informalexample>

<para xml:id="p5b">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:</para>

<informalexample>
<para xml:id="p5c"><link xlink:href="http://norman.walsh.name/2005/02/witw/is?userid=ndw&amp;nearby=0">http://norman.walsh.name/2005/02/witw/is?userid=ndw&amp;nearby=0</link></para>
</informalexample>
</section>

<section xml:id="whereami">
<title>Where I Am</title>

<para xml:id='p6'>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.</para>

<para xml:id='p7'>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
also use <systemitem class="protocol">https:</systemitem> but that requires
certificates and things that don't seem quite so simple, so I'm not going
to worry about that right now.</para>

<para xml:id='p8'>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.</para>

<para xml:id='p9'>If you walk through a simple
<link xlink:href="/2005/02/witw/register">registration procedure</link>,
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.</para>

<para xml:id='p10'>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:</para>

<programlisting><![CDATA[<location xmlns="http://nwalsh.com/xmlns/witw-post#">
<latlong>
<lat>37.7667</lat>
<long>-122.4167</long>
</latlong>
</location>]]></programlisting>

<para xml:id='p11'>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:</para>

<programlisting><![CDATA[<location xmlns="http://nwalsh.com/xmlns/witw-post#">
<landmark>
<name>Logon International Airport</name>
</landmark>
</location>]]></programlisting>

<para xml:id='p12'>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
<uri>http://norman.walsh.name/2005/02/witw/ami/now</uri> sending a document
that conforms to 
<link xlink:href="examples/ami-request.rnc">this schema</link>
(in 
<link xlink:href="examples/ami-request.xsd">XSD</link>, if you prefer):</para>

<programlisting><![CDATA[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>]]></programlisting>

<para xml:id='p13'>The replies are XML documents that conform to
<link xlink:href="examples/ami-reply.rnc">this schema</link>
(in 
<link xlink:href="examples/ami-reply.xsd">XSD</link>, if you prefer).</para>
</section>

<section xml:id="symmetry">
<title>Symmetry</title>

<para xml:id='p14'>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.</para>

<para xml:id='p15'>To that end, you can retrieve a location by doing
a POST to the <uri>http://norman.walsh.name/2005/02/witw/is</uri> address.
Your request must conforms to 
<link xlink:href="examples/is-request.rnc">this schema</link>
(in 
<link xlink:href="examples/is-request.xsd">XSD</link>, if you prefer).</para>

<para xml:id='p16'>And if you do a simple GET on the
<uri>http://norman.walsh.name/2005/02/witw/ami/now</uri> address, you'll
get back an HTML form that you can use to do the POST, which seems
quite convenient.
</para>
</section>

<section xml:id="next">
<title>Next Steps</title>

<para xml:id='p17'>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.</para>

<para xml:id='p18'>In the meantime, comments most welcome. Several
people commented on <link xlink:href="../15/ws-wtf">the first essay</link>
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.</para>

</section>
</essay>
