The leading directory for SOAP 1.1 developers.


A Busy Developer's Guide to SOAP 1.1

By Dave Winer, Jake Savin, UserLand Software, 4/2/01.

This document describes a subset of SOAP 1.1 that forms a basis for easy interoperation between different environments. When we refer to "SOAP" in this document we're referring to this subset of SOAP, not the full SOAP 1.1 specification.

Overview 

For the purposes of this document, SOAP is a Remote Procedure Calling protocol that works over HTTP.

The body of the request is in XML. A procedure executes on the server and the value it returns is also formatted in XML.

Procedure parameters and returned values can be scalars, numbers, strings, dates, etc.; and can also be complex record and list structures.

Request example 

Here's an example of a SOAP request:

POST /examples HTTP/1.1
User-Agent: Radio UserLand/7.0 (WinNT)
Host: localhost:81
Content-Type: text/xml; charset=utf-8
Content-length: 474
SOAPAction: "/examples"

<?xml version="1.0"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
   <SOAP-ENV:Body>
      <m:getStateName xmlns:m="http://www.soapware.org/">
         <statenum xsi:type="xsd:int">41</statenum>
         </m:getStateName>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

Header requirements 

The format of the URI in the first line of the header is not specified. For example, it could be empty, a single slash, if the server is only handling SOAP calls. However, if the server is handling a mix of incoming HTTP requests, we allow the URI to help route the request to the code that handles SOAP requests. (In the example, the URI is /examples, telling the server to route the request to the "examples" responder.)

A User-Agent and Host must be specified.

The Content-Type is text/xml. The charset may be specified, if not, the default is US-ASCII. Other acceptable charsets are UTF-8 and UTF-16. UTF-8 is recommended for maximum interop. See the note on UTF character encodings, below.

The Content-Length may be specified, if it is, it must be correct.

As with the URI in the first line, SOAPAction is used to route the request to a handler on the server that will respond. It's entirely up to the application to determine how this header element is used. In many implementations the URI and the SOAPAction header will have the same value.

Payload format 

The payload is in XML, a single <SOAP-ENV:Envelope> element.

All the attributes of the <SOAP-ENV:Envelope> are required as shown in the example above.

The <SOAP-ENV:Envelope> must contain a single <SOAP-ENV:Body> element, which contains a single element which is the procedure call. The name of the procedure is the name of this element. Note that the procedure name must be a valid XML element name.

The elements contained within the procedure call are the parameters to the procedure. The names of the parameters is significant, the order of the parameters are not. Parameter type is indicated by the xsi:type attribute.

For example, the procedure name could be the name of a file containing a script that executes on an incoming request. It could be the name of a cell in a database table. Or it could be a path to a file contained within a hierarchy of folders and files.

A procedure call may take no parameters, if so, the procedure element must not contain sub-elements.

Scalar values 

The following scalar value types are supported by this subset of SOAP 1.1.

Type valueTypeExample
xsd:int32-bit signed integer-12
xsd:booleana boolean value, 1 or 01
xsd:stringstring of characters hello world
xsd:float or xsd:doublesigned floating point number -12.214
xsd:timeInstantdate/time 2001-03-27T00:00:01-08:00
SOAP-ENC:base64 base64-encoded binaryeW91IGNhbid0IHJlYWQgdGhpcyE=


Structs 

A value can also be a struct, which is specified by an XML element that contains sub-elements. structs can be nested, and may contain any other type, including an array, described below.

Here's an example of a two-element struct:

<param>
   <lowerBound xsi:type="xsd:int">18</lowerBound>
   <upperBound xsi:type="xsd:int">139</upperBound>
   </param>

The names of struct elements are significant, the order of the elements is not.

Arrays 

A value can also be an array, which is specified by an XML element with a SOAP-ENC:arrayType attribute whose value begins with ur-type[, followed by the number of array elements, followed by ].

Here's an example of a four-element array:

<param SOAP-ENC:arrayType="xsd:ur-type[4]" xsi:type="SOAP-ENC:Array">
   <item xsi:type="xsd:int">12</item>
   <item xsi:type="xsd:string">Egypt</item>
   <item xsi:type="xsd:boolean">0</item>
   <item xsi:type="xsd:int">-31</item>
   </param>

The order of array elements is significant, the names of the elements are not.

You can mix types as the example above illustrates.

If the array elements are of a single type, the value of the array element's SOAP-ENC:arrayType specifies the type of the array's sub-elements, for example, SOAP-ENC:arrayType="xsd:int[4]" means an array of four xsd:int elements.

For mixed-type arrays, the SOAP-ENC:arrayType attribute always specifies xsd:ur-type.

For single-type arrays, the xsi:type attribute is optional for array item sub-elements, but its inclusion is recommended.

Null values 

A value can also be a null, which is specified by an XML element with an attribute, xsi:null, whose value is 1 as follows: <param1 xsi:null="1"/>.

Response example 

HTTP/1.1 200 OK
Connection: close
Content-Length: 499
Content-Type: text/xml; charset=utf-8
Date: Wed, 28 Mar 2001 05:05:04 GMT
Server: UserLand Frontier/7.0-WinNT

<?xml version="1.0"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
   <SOAP-ENV:Body>
      <m:getStateNameResponse xmlns:m="http://www.soapware.org/">
         <Result xsi:type="xsd:string">South Dakota</Result>
         </m:getStateNameResponse>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>

Response format 

Unless there's an error, return 200 OK.

The Content-Type is text/xml.

Content-Length may be specified, if it is, it must be correct.

The body of the response is in XML, a single <SOAP-ENV:Envelope> element.

The <SOAP-ENV:Envelope> must contain a single <SOAP-ENV:Body> element, which contains a single element which is the returned value of the procedure.

The single element contained in the <SOAP-ENV:Body> has an arbitrary name which must match the name of the procedure that was called, with the word "Response" tacked on to the end of its name. Let's call this element the wrapper for the response. Even this is not the actual value of the response, which is contained in the single optional sub-element of the wrapper and must be a valid parameter.

The namespace of the wrapper element should match the namespace in the request.

If the wrapper has no sub-elements then the procedure did not return a value

Fault example 

HTTP/1.1 500 Server Error
Connection: close
Content-Length: 511
Content-Type: text/xml; charset=utf-8
Date: Wed, 28 Mar 2001 05:06:32 GMT
Server: UserLand Frontier/7.0-WinNT

<?xml version="1.0"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Client</faultcode>
         <faultstring>Can't call getStateName because there are too many parameters.</faultstring>
         </SOAP-ENV:Fault>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>

Fault format 

If there's an error return 500 Server Error.

The <SOAP-ENV:Body> may contain a <SOAP-ENV:Fault> which must contain two elements, <faultcode> and <faultstring>.

<faultcode> is intended for use by software to provide an algorithmic mechanism for identifying the fault. <faultstring> is intended to provide a human-readable explanation of the fault.

A <SOAP-ENV:Body> may not contain both a <SOAP-ENV:Fault> and a wrapper (returned value).

When to fault 

If you can't process a request, for any reason, you must generate a fault.

Examples of fault conditions include:

1. An element or attribute in a request that is in an XML namespace which has not been declared.

2. A header in the request with a mustUnderstand="1" attribute that you don't understand.

3. A parameter is of a type that you don't support.

Notes 

For UTF character encodings, a Byte-Order Mark (BOM), represented as the Unicode character, U+FEFF (ZERO WIDTH NO-BREAK SPACE), may be added as the first character of the payload. This would appear as 0xEFBBBF, 0xFEFF or 0xFFFE when encoded as UTF-8, big-endian UTF-16 or little-endian UTF-16, respectively. A BOM is not required except when the encoding is UTF-16, and should not be used unless necessary.

Pointers 

XML-RPC for Newbies provides a top-level explanation of RPC in XML over HTTP.

Unstalling SOAP outlines the motivation for the writing of this document.

The development of BDG was guided by the soapbuilders list.

Discussion also took place on the XML-RPC discussion group.

Questions and comments regarding this document may be posted on the soapbuilders list, the soap-newbies list, or in the discussion group on soapware.org.

Announce new BDG-level implementations in the discussion group.

Strategies/Goals 

Interop. First and foremost, the purpose of a wire protocol such as SOAP 1.1 is interoperation, giving users and developers choice, eliminating lock-in, and keeping the market open to all size organizations, commercial and open source development, individual developers and hobbyists.

Strict standards compliance. Where this specification is not in compliance with the SOAP 1.1 specification, or the XML 1.0 specification, as of 4/2/01, this specification will change.

Discoverability. It should be possible for an HTML coder to be able to look at a wire-level SOAP procedure call, understand what it's doing, and be able to modify it and have it work on the first or second try.

Firewalls. No new power is provided beyond the capabilities of HTTP-POST. Firewall software can watch for POSTs whose Content-Type is text/xml or (even better) watch for the presence of a SOAPAction header and apply whatever policies they see fit.

Easy to implement. We wanted an easy to implement subset of SOAP 1.1 that could quickly be adapted to run in many environments. It must work well in static environments such as C, C++ and Java, as well as dynamic scripting environments such as Perl, Visual Basic, Python and PHP.

Gratitude 

Thanks to Joshua Allen, Michael Brennan, Dick Brooks, David Crowley, Bob Cunnings, Simon Fell, Tony Hong, Oisin Hurley, Eric Kidd, Paul Kulchenko, Fredrik Lundh, Mark Nottingham, Sam Ruby, Brent Simmons, Hannes Wallnöfer, and the soapbuilders and xml-rpc lists for their patience, good humor and guidance in developing and refining this document.

What does the future hold? 

This Busy Developer's Guide was written with one audience in mind, busy developers like ourselves, who love to build applications on the Internet, but already have a Day Job. We wrote this document, Jake and myself, simply because we needed it, and in the spirit of the Web, of course we wanted to share it with everyone.

That there's a need for such a thing surprises some, considering that the S in SOAP stands for Simple. In fact, SOAP is simple, as this document shows, even though coaxing its simplicity from the myriad of related specs and RFCs requires a patience and dedication that most BDs don't have.

And there's more to SOAP that we don't yet fully understand. As of this writing, in April 2001, there's an active community of expert hard-working honest developers digging into SOAP interop that goes beyond what's written here in the BDG.

So perhaps this is just a first step? No one knows, but there are people working on it. There may be more BDG-style documents, and we may participate in writing them, but for now, our focus is on deploying applications, and delivering on the promise of SOAP. Cool applications for the Internet, choice for users, and freedom for developers.

We have so many ideas, and so much fun stuff to do. We're gathering pointers to applications created by members of the SOAP developer community, in the services section of the SoapWare.Org directory. We hope this section builds out to be a very bushy tree very quickly.

We also have a discussion group here on SoapWare.Org where we would be happy to receive your comments, questions and suggestions.

Here's to a bright future for you, for us and for SOAP!

Dave Winer
April 2, 2001

Home |  About |  Validator |  Hosting |  Weblog | Join Now | Login

© Copyright 2000-2009 UserLand Software, Inc.

Create your own Manila site in minutes. Everyone's doing it!