<?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 II: SOAP RPC</title>
<volumenum>8</volumenum>
<issuenum>25</issuenum>
<pubdate>2005-02-18T09:12:11-05:00</pubdate>
<date>$Date$</date>
<author><personname>
<firstname>Norman</firstname><surname>Walsh</surname>
</personname></author>
<copyright><year>2005</year><holder>Norman Walsh</holder></copyright>
<abstract>
<para>Keeping track of your location with SOAP RPC.</para>
</abstract>
<!--
<dc:coverage rdf:resource="http://norman.walsh.name/knows/where/"/>
-->
</info>

<para xml:id='p1'>My second interface to
<link xlink:href="../15/ws-wtf">Where In The World</link> is
a set of methods that you can invoke using
<link xlink:href="http://www.w3.org/TR/2003/soap12-part0/#L1185">SOAP RPC</link>.
I'm not sure I really understand all the jargon yet, but I think the
salient bits are:</para>

<variablelist>
<varlistentry>
<term>The target SOAP node</term>
<listitem>
<para xml:id='p7'>That's “<uri>http://norman.walsh.name/2005/02/witw/soap</uri>”
for the “where is someone” services and
“<uri>http://norman.walsh.name/2005/02/witw/ami/soap</uri>” for the
“where I am” services that require authentication. (In fact, the latter
node will perform all of the services.)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>The namespace of the services</term>
<listitem>
<para xml:id='p8'>That's “<uri>http://norman.walsh.name/witw</uri>”. I'd have made that a
dated URI, but I'm using
<link xlink:href="http://en.wikipedia.org/wiki/Perl">Perl</link>’s
<link xlink:href="http://cpan.uwinnipeg.ca/module/SOAP::Lite">SOAP::Lite</link>
module to do the implementation
and there was some weirdness in the way that the namespace
name was mapped to the Perl module name. I decided to just punt.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>The names of the methods</term>
<listitem>
<para xml:id='p9'>They are “<methodname>user</methodname>”, “<methodname>is</methodname>”,
“<methodname>nearby</methodname>”,
“<methodname>atlatlong</methodname>”, and “<methodname>atlandmark</methodname>”,
described below.</para>
</listitem>
</varlistentry>
</variablelist>

<para xml:id='p10'>As you may have noticed, I've decomposed things a little bit
differently. I did that to make some of the return types more
manageable.</para>

<section xml:id="user">
<title>User</title>

<para xml:id='p11'>The <methodname>user</methodname> method returns
information about a <parameter>userid</parameter>:</para>

<methodsynopsis xml:id="f.user">
  <methodname>user</methodname>
  <methodparam>
    <type>xs:string</type>
    <parameter>userid</parameter>
  </methodparam>
  <exceptionname>UnknownUser</exceptionname>
</methodsynopsis>

<para xml:id='p12'>It returns the <parameter>userid</parameter>, the
<parameter>name</parameter> of the user, a hash
(in the
<link xlink:href="http://xmlns.com/foaf/0.1/#term_mbox_sha1sum">mbox_sha1sum</link>-style
of <link xlink:href="http://en.wikipedia.org/wiki/FOAF">FOAF</link>)
of the user's
<parameter>email</parameter> address, and the
<parameter>uri</parameter> associated with the user.</para>

<para xml:id='p13'>If the specified <parameter>userid</parameter> is unknown,
the service faults.</para>

</section>

<section xml:id="is">
<title>Is</title>

<para xml:id='p14'>The <methodname>is</methodname> method returns information about the
location of the specified <parameter>userid</parameter>.</para>

<methodsynopsis xml:id="f.is">
  <methodname>is</methodname>
  <methodparam>
    <type>xs:string</type>
    <parameter>userid</parameter>
  </methodparam>
  <exceptionname>UnknownUser</exceptionname>
  <exceptionname>UnknownLocation</exceptionname>
</methodsynopsis>

<para xml:id='p15'>It returns the <parameter>userid</parameter>, the
<parameter>date</parameter> when the location was specified, the
<parameter>latitude</parameter> and the
<parameter>longitude</parameter> specified by the user.
</para>

<para xml:id='p21'>It faults if the <parameter>userid</parameter> is unknown or if the
user has not specified a location.</para>
</section>

<section xml:id="nearby">
<title>Nearby</title>

<para xml:id='p16'>The <methodname>nearby</methodname> method returns information about
landmarks that are close to the
location of the specified <parameter>userid</parameter>.</para>

<methodsynopsis xml:id="f.nearby">
  <methodname>nearby</methodname>
  <methodparam>
    <type>xs:string</type>
    <parameter>userid</parameter>
  </methodparam>
  <methodparam choice="opt">
    <type>xs:string</type>
    <parameter>units</parameter>
    <initializer>"mi"</initializer>
  </methodparam>
  <methodparam choice="opt">
    <type>xs:decimal</type>
    <parameter>distance</parameter>
    <initializer>50.0</initializer>
  </methodparam>
  <exceptionname>UnknownUser</exceptionname>
  <exceptionname>UnknownLocation</exceptionname>
  <exceptionname>InvalidUnits</exceptionname>
  <exceptionname>InvalidDistance</exceptionname>
</methodsynopsis>

<para xml:id='p17'>The <parameter>units</parameter> and <parameter>distance</parameter>
parameters are optional. If specified, <parameter>units</parameter> must be
one of “<literal>mi</literal>”, “<literal>km</literal>”,
“<literal>m</literal>”, or “<literal>ft</literal>”. The default
distance is 50 miles (about 80km).</para>

<para xml:id="p4">It returns zero or more sequences of landmarks:
the <parameter>name</parameter> of the landmark, its
<parameter>latitude</parameter>, <parameter>longitude</parameter>,
any <parameter>URI</parameter> associated with the landmark, and
its <parameter>distance</parameter> from the user.</para>

<para xml:id='p22'>It faults if the <parameter>userid</parameter> is unknown, if the
user has not specified a location, if the units are invalid, or if
the distance is invalid.</para>

</section>

<section xml:id="atlatlong">
<title>At Latitude and Longitude</title>

<para xml:id='p18'>The <methodname>atlatlong</methodname> method allows a user to specify
their location. You must use the authenticated SOAP node
(<uri>http://norman.walsh.name/2005/02/witw/ami/soap</uri>) in order
to access this method and the <parameter>userid</parameter> specified
must match the authenticated user.</para>

<methodsynopsis xml:id="f.atlatlong">
  <methodname>atlatlong</methodname>
  <methodparam>
    <type>xs:string</type>
    <parameter>userid</parameter>
  </methodparam>
  <methodparam>
    <type>xs:decimal</type>
    <parameter>latitude</parameter>
  </methodparam>
  <methodparam>
    <type>xs:decimal</type>
    <parameter>longitude</parameter>
  </methodparam>
  <exceptionname>AuthorizationRequired</exceptionname>
  <exceptionname>InvalidUser</exceptionname>
  <exceptionname>UnknownUser</exceptionname>
  <exceptionname>InvalidLatitude</exceptionname>
  <exceptionname>InvalidLongitude</exceptionname>
</methodsynopsis>

<para xml:id="p5">It returns the <parameter>userid</parameter> if it
succeeds or throws a SOAP fault.</para>
</section>

<section xml:id="atlandmark">
<title>At Landmark</title>

<para xml:id='p19'>The <methodname>atlandmark</methodname> method allows a
user to specify that they are at a particular landmark. Like the
<methodname>atlatlong</methodname> method, you must use the
authenticated SOAP node
(<uri>http://norman.walsh.name/2005/02/witw/ami/soap</uri>) in order
to access this method and the <parameter>userid</parameter> specified
must match the authenticated user.</para>

<methodsynopsis xml:id="f.atlandmark">
  <methodname>atlandmark</methodname>
  <methodparam>
    <type>xs:string</type>
    <parameter>userid</parameter>
  </methodparam>
  <methodparam>
    <type>xs:string</type>
    <parameter>landmark</parameter>
  </methodparam>
  <exceptionname>AuthorizationRequired</exceptionname>
  <exceptionname>InvalidUser</exceptionname>
  <exceptionname>UnknownUser</exceptionname>
  <exceptionname>UnknownLandmark</exceptionname>
</methodsynopsis>

<para xml:id="p20">It returns the <parameter>userid</parameter> if it
succeeds or throws a SOAP fault.</para>
</section>

<section xml:id="sample">
<title>Sample Code</title>

<para xml:id='p23'>On the assumption that any who's read this far won't be scared
off by a few lines of code, here's
<link xlink:href="examples/witw.soap.pl">a short Perl script</link>
that returns
the latitude and longitude of a user.</para>

<programlisting><textobject>
<textdata fileref="examples/witw.soap.pl"/>
</textobject></programlisting>

<para xml:id='p24'>This morning, if you pass it <literal>ndw</literal>,
it tells you I'm at home:</para>

<programlisting><prompt>$</prompt> <command>perl</command> witw.soap.pl ndw
Norman Walsh was last seen at 42.34N, 72.45W.
That was on 2005-02-17T21:35:42Z.</programlisting>

<para xml:id="p25">To satisfy my own curiosity, I wrote
<link xlink:href="examples/witw.xml.pl">a Perl script</link>
to get the same
information using the brute force API:</para>

<programlisting><textobject>
<textdata fileref="examples/witw.xml.pl"/>
</textobject></programlisting>

<para xml:id='p26'>The two styles of API are clearly quite different, but
I'll reserve judgement until I've done a few more experiments.</para>

</section>
</essay>
