SimpleSOAP documentation

$Id: index.html,v 1.3 2005/05/23 20:48:40 rich Exp $

Introduction

SimpleSOAP is an early, experimental SOAP client for Objective CAML.

It was written by Richard W.M. Jones. For updates, please see the Merjis developers' website. For support please post on the OCaml mailing lists.

Theory of operation

To call a remote SOAP service, you have to define the URL(s) of the service, and the types and functions accepted by the service. With SimpleSOAP you do this by writing an interface file, which looks similar to an ordinary OCaml .mli file.

For example:

URI "http://localhost:8080/campaign_service"

type campaign = {
  dailyBudget : int;
  id : int;
  name : string;
}

val set_campaign : campaign -> unit
val get_campaign : unit -> campaign

This file is then parsed, using a set of camlp4 macros, into stub functions (written in OCaml).

You can then call these stub functions in the usual way, eg. let campaign = Campaign_service.get_campaign (). The stub functions actually handle the details of making the SOAP call to the remote server and parsing the reply.

Because SimpleSOAP is at a very early stage of development, you may find that you need to examine, and possibly even fix, the stub functions generated. This is possible, and is discussed below.

SimpleSOAP uses PXP, ocamlnet and equeue to generate XML and issue HTTP requests to servers.

SimpleSOAP and SimpleSOAP.Helpers

SimpleSOAP comes with a library of useful functions and types, in a module called SimpleSOAP. See simpleSOAP.mli for a description of the functions available.

The stub functions use helpers to complete their work. These are located in the SimpleSOAP.Helpers module, and should not be called directly by other code.

Compiling the interface into stubs

Once you have written your interface file, which must have extension .ml (even though it looks like an mli file), compile it into stubs using:

ocamlc -I +pcre -I +equeue -I +netstring -I +netclient -I +pxp-engine \
       -pp "camlp4o ./pa_soapclientstubs.cmo" \
       -I +camlp4 -c your_api.ml

You could also use ocamlopt.

Printing out the stubs (for debugging SimpleSOAP)

To debug SimpleSOAP, you should be able to see the generated stubs. To print these out, use:

camlp4o ./pa_soapclientstubs.cmo pr_o.cmo your_api.ml | less

Writing interface files

Interface files have the general form:

type declarations

URI "url"

function prototypes

Type declarations look just like ordinary OCaml types, for example:

type campaign = {
  dailyBudget : int;
  id : int;
  name : string;
}

The URI line gives the URL (actually the "namespace") of the service. This will be given to you by the service provider.

Function prototypes look like ordinary OCaml function declarations, as found in .mli files, for example:

val set_campaign : campaign -> unit
val get_campaign : unit -> campaign

You can have several "URI" lines in the file - each one affects subsequent function prototypes until the next URI line is reached.

Calling the interface - what stubs are generated

For each function prototype, two functions are in fact generated, and neither looks exactly like the prototype. For example a function declared as:

val get_campaign : unit -> campaign

generates these two actual functions which you can call:

val get_campaign : ?soap:SimpleSOAP.extra_in -> unit -> campaign
val get_campaign__x : ?soap:SimpleSOAP.extra_in -> unit -> campaign * SimpleSOAP.extra_out

The optional ?soap parameter carries extra information into the function. Normally you will never use it, but it can be used to send extra headers in the SOAP request, which some services will require.

The variant function get_campaign__x returns the normal result and extra data in a tuple. The extra data contains, among other things, extra headers returned in the SOAP response.

For each type declaration, two functions are generated, although generally you will never need to call them directly:

val name_of_soap : SimpleSOAP.Helpers.node -> name
val soap_of_name : name -> SimpleSOAP.Helpers.node

Limitations

Parameters to stubs

Only basic OCaml types, types declared in type declarations, and lists of these, are permitted as parameters to stubs.

The return value from a stub is similarly limited.

SOAP can, in theory, return multiple values from a single call. This is rarely used because so few languages actually allow it. At present we don't support this, but we may do so in future.

Type declarations

Records containing option-al fields are handled specially, but optional values elsewhere probably won't be understood by any server.

Type information

SOAP supports sending type information with parameters, but at the moment we neither send type information, nor understand it in the response.

Notes

Calling https (http over SSL) services

Ocamlnet does not support SSL, but you can still call https services with the help of stunnel.

You will need to run stunnel in client proxy mode, as follows:

stunnel -c -d 8081 -r remote.example.com:https

Modify your URI lines so that instead of referencing the remote server, they reference the stunnel endpoint, eg.:

URI "http://localhost:8081/remote_service/"

Richard W.M. Jones
Last modified: Mon May 23 21:42:46 BST 2005