From: Joshua Taylor
Subject: SOAP in Lisp
Date: 
Message-ID: <c9bc56f1-88a5-45a2-a17f-811c68dca4ea@e38g2000yqa.googlegroups.com>
Hi all,

I'm doing a bit of work that involves calling some webservices that
happen to use SOAP [1], particularly SOAP 1.1 [2]. At the moment, I'm
manually constructing SOAP messages using ClosureXML [3]. The things
I'm working on at the moment are simple enough that this isn't a huge
hassle, but I do end up reading a number of WSDL [4] files and
manually creating corresponding structures/classes/&c.

Of course, as I do a few more of these, I'm starting to think that it
would make more sense to abstract and bundle up the SOAP stuff into a
separate library. Before I go and do that though, I'd like to have an
idea what other people are already doing when they have to work with
SOAP. Here are the relevant things of which I'm aware:

* There is already a CL-SOAP [5]. However, it appears to be
unfinished, and the last update time on the site is 2005/10/09. Is
anyone using this? How is it?
* Franz has a  SOAP API [6]. However, it's not complete either, as of
8.1: "This document describes an implementation of the Allegro CL SOAP
API. There are still pieces of the Allegro CL/SOAP implementation to
be completed. These will be released when they are ready."

Apart from those, a quick Googling for SOAP and Lisp also gets me a
lemonodor announcement of the Franz API, and Bill Clementson talking
about web services in Lisp. Those are from 2003 and 2004,
respectively.

The Franz API looks like it would do what I need, but I'm not sure
whether Allegro is actually an option for me. However, if I hear that
the people like the API, I wouldn't be too averse to trying to support
the same API, in the same way that PURI [7] uses a very similar API to
Franz's net.uri [8]. I'm not sure whether that's permitted or not,
though.

So what do you all do when you need to work with SOAP? What would do
if you had your choice?

//JT

[1] http://www.w3.org/TR/soap/
[2] http://www.w3.org/TR/2000/NOTE-SOAP-20000508/
[3] http://common-lisp.net/project/cxml/index.html
[4] http://www.w3.org/TR/wsdl
[5] http://common-lisp.net/project/cl-soap/
[6] http://www.franz.com/support/documentation/8.1/doc/soap.htm
[7] http://puri.b9.com/
[8] http://opensource.franz.com/uri/
From: gtod
Subject: Re: SOAP in Lisp
Date: 
Message-ID: <21b77c38-e5db-455b-80df-b3e9b8d92f4c@v13g2000pro.googlegroups.com>
On Mar 20, 8:39 am, Joshua Taylor <···········@gmail.com> wrote:
> So what do you all do when you need to work with SOAP? What would do
> if you had your choice?

We did it by hand - that is we had a template file for each soap
request we needed to make:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
  <keepAlive xmlns="bf">
    <request>
      <header>
        <clientStamp>0</clientStamp>
        <sessionToken>${var session_token}</sessionToken>
      </header>
    </request>
  </keepAlive>
</soap:Body>
</soap:Envelope>

This uses a ruby csTemplate style as these templates came over from a
ruby project.  Of course in Lisp you could do this in a more CL-WHO
style.  This may not even be a properly formed SOAP request, I simply
made these templates as small as possible through repeated testing of
what the soap server would accept ;)

We'd populate the template with data at runtime and send it to the
soap server and then use some cffi bindings on expat to parse the XML
response and build our own CLOS/list based version of the response.  A
macro let us write things like:

(define-soap-class runner
    ()
 ((asian-line-id :xml "asianLineId" :soap-type :int)
  (handicap :xml "handicap" :soap-type :double)
  (name :xml "name" :soap-type :string :reader name)
  (sid :xml "selectionId" :soap-type :int :reader sid))
 (:xml "n2:Runner"))

to define the form of the soap responses.  Thanks to John Fremlin.

I have only used SOAP on this one project but it seemed very bloated
to me so I gravitated to this solution which ignores the SOAP spec
support of error handling and data types and as I say did everything
by hand.

I imagine the limitations of such an approach are obvious to you but
it has worked well for us in our narrow domain.

If I had my time again I would use a full featured CL SOAP library
that was well designed and fast and available for more than one
implementation.  Not sure such a thing exits...