An Outline of the Web Services Binding:

16th October 2001

1. Overview
2. Example
        2.1. Create a connection
        2.2. Set an option on a connection
        2.3. Search
        2.4. Fetch record
3. Refinements to the basic model
        3.1. Create a connection, set an option, search and fetch a record
        3.2. Multiple server responses
        3.3. More optimisations
        3.4. Multiple records
4. Now what?

1. Overview

In the Web Services environment, there are no ``objects'' in the traditional sense: unlike CORBA, there is no client-side object that acts as a proxy for the ``real'' object on the server side.

But that's not a problem. The server represent the ZOOM objects (connections, result sets, etc.) by means of ``object handles'' - opaque cookies which the server gives to the client when it creates and object, and which the client passes back to the server when it wants to invoke a remote method.

So ``creating a connection'' in the Web Services binding is essentially a matter of asking the server for an opaque cookie to act as a connection handle. That's your ``object'': you submit that along with other parameters to do a search, and what you get back includes another opaque cookie which is the handle for the object representing the result set.

2. Example

Before we plough in, a warning: these examples are very much off the top of the head. URL paths and parameter names will almost certainly change before this specification is formalised. Do not take it too seriously. But if you want to go ahead and build a prototype implementation, then please feel free!

2.1. Create a connection

Client request:
HTTP GET /zoom/ws/connect

No parameters are needed: the hostname and port are implicit as they've already been given to the HTTP protocol in which this is wrapped.

Server response:
666f6f626172

That's all there is in the HTTP body: no SOAP-like wrapper.

2.2. Set an option on a connection

Client request:
HTTP GET /zoom/ws/conn/option?conn=666f6f626172&databaseName=Voyager

Server response:
Default

This was previous value of the databaseName option.

2.3. Search

Client request:
HTTP GET /zoom/ws/conn/search?conn=666f6f626172&prefix=@attr+1=7+0253333490

Server response:
74687269636b656e

This is a new result-set handle.

2.4. Fetch record

Client request:
HTTP GET /zoom/ws/rs/get?rs=74687269636b656e&which=1

Server response:
000  01109cam  2200277 a 4500
001  708964
005  19980710092633.8
008  970604s1997    inuab    b    001 0 eng  
035      $9(DLC)   97023698
906      $a7$bcbc$corignew$d1$eocip$f19$gy-gencatlg
955      $apc16 to ja00 06-04-97; jd25 06-05-97; jd99 06-05-97; jd11 06-06-97;aa05 06-10-97; CIP ver. pv08 11-05-97
010      $a   97023698 
020      $a0253333490 (alk. paper)
040      $aDLC$cDLC$dDLC
050  00  $aQE862.D5$bC697 1997
082  00  $a567.9$221
245  04  $aThe complete dinosaur /$cedited by James O. Farlow and M.K. Brett-Surman ; art editor, Robert F. Walters.
260      $aBloomington :$bIndiana University Press,$cc1997.
300      $axi, 752 p. :$bill. (some col.), maps ;$c26 cm.
504      $aIncludes bibliographical references and index.
650   0  $aDinosaurs.
700  1   $aFarlow, James Orville.
700  2   $aBrett-Surman, M. K.,$d1950-
920      $a**LC HAS REQ'D # OF SHELF COPIES**
991      $bc-GenColl$hQE862.D5$iC697 1997$tCopy 1$wBOOKS
991      $br-SciRR$hQE862.D5$iC697 1997$tCopy 1$wGenBib bi 98-003434

That is, just the MARC record: no junk wrapped around it.

3. Refinements to the basic model

There are refinements to be made here, but the point is that that ZOOM's OO model works perfectly well in the Web Services world - just as it does in non-OO languages such as C We are merely using HTTP as the means by which we invoke a method on a remote object.

The refinements, of course, are mostly to do with efficiency. In Real Lifetm, every HTTP request inexplicably still requires a new TCP/IP connection to be forged and then torn down, with all the DNS overhead and suchlike - so the session above will run like a dog. Even for servers and clients that can successfully do HTTP 1.1 keep-alive behaviour, four round-trips is a lot of overhead. So you can see why the SRU people want to wrap all this information up in one transaction.

I think we can do that without breaking the model, though. All we need to do is define an ecapsulation method for wrapping multiple operations in a single URL, and introduce special connection and result-set names to mean ``the one you just thought of''. Sort of like this:

3.1. Create a connection, set an option, search and fetch a record

Client request:
HTTP GET /zoom/ws/series:
	connect;
	conn/option?conn=LAST&databaseName=Voyager;
	conn/search?conn=LAST&prefix=@attr+1=7+0253333490;
	rs/get?rs=LAST&which=1
  
Server response:
000  01109cam  2200277 a 4500
001  708964
005  19980710092633.8
etc.

3.2. Multiple server responses

We might want to think about how to have the server's response also include the connection ID, the old option-name and the result-set ID as well as the record.

The ``obvious'' answer in the HTTP would is probably a MIME multipart/mixed, but that seems pretty heavyweight to me. I prefer not to drag all that technology in unless we really need it. (Also, the name multipart/mixed sucks, since what it actually means is ``the opposite of multipart/alternative''. It ought to be called multipart/serial, especially since all the parts may well be of the same MIME-type. Ho hum.)

3.3. More optimisations

Further refinements then become obvious: instead of referring to conn=LAST, we could use conn=NEW (and omit the connect; bit altogether) to tell the server that we're not going to re-use this connection object, so there's no need to give us an ID.

Then we could say that the conn= parameter may omitted from any of the method calls in a session, in which case NEW is implicitly assumed.

We could similarly have the rs= bit default to LAST. So our putative client request is down to:

HTTP GET /zoom/ws/series:
	conn/option?databaseName=Voyager;
	conn/search?prefix=@attr+1=7+0253333490;
	rs/get?which=1

But the original four-stage version is still a part of the protocol, so you can re-use connections (``sessions'', if you like) and result-sets. We want to be able to do more than one-hit search-and-retrieve transactions.

3.4. Multiple records

Another important refinement, of course, is returning multiple records, as required by a client request such as rs/get?which=11&count=10.

This is left as an exercise for the reader.

4. Now what?

The meta-question that springs to mind here is: to what extent are we reinventing SRU? How close is what we're proposing to the SRU proposal?

If the answer is ``pretty damned close'' then should we (A) abandon work on a Web Services binding for ZOOM, or (B) carefully massage our parameter names and defaults so that they closely resemble SRU? Then we can ``kidnap'' SRU and rebrand it as ``the web-services binding for ZOOM''.

I'm not sure how serious I am about that. Probably somewhere in the region of 2%-98% serious.

Feedback to <mike@indexdata.com> is welcome!