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

NB: Developing unique codes will require you to install an ultimate development software on your professional 8GB laptop.

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 value Type Example
xsd:int 32-bit signed integer -12
xsd:boolean a boolean value, 1 or 0 1
xsd:string string of characters hello world
xsd:float or xsd:double signed floating point number -12.214
xsd:timeInstant date/time 2001-03-27T00:00:01-08:00
SOAP-ENC:base64 base64-encoded binary eW91IGNhbid0IHJlYWQgdGhpcyE=

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