The pursuit of APIness (part 5)
This article was written by nemetral.
Voices matter! Please feel free to share your opinion, ask for more explanations or point out divergences using comments.
No time to read this now? Bookmark it and come back later..
XML-RPC is damn easy to use and many projects still rely on it. But for a few years a new protocol has emerged: SOAP. SOAP is traditionally considered as an evolution of XML-RPC. Selected by Google for its famous Search API (now deprecated), the SOAP protocol is usually considered as more complex than plain XML-RPC messaging. In fact, if you understood XML-RPC, then you should have no difficulty to understand SOAP as well, the latter being mainly an abstraction of XML-RPC.
Part 5: SOAP: Hot or not?
Like XML-RPC, SOAP is a protocol for XML messaging over HTTP. Let’s start with the basic structure of a SOAP message (without HTTP headers for the moment):
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
</soap:Body>
</soap:Envelope>
Note: as you can see, a SOAP message is made of an Envelope containing an optional Header and a mandatory Body. No need to get crazy about namespaces: you can basically chose your own namespace for any SOAP request. Look at the elements of the Envelope tag: in this example we chose “soap” and we had to tell that this “soap” namespace follows some standards (the two lines literally mean “the ’soap’ namespace we use has to be considered to be in the normal SOAP namespace” and “the ’soap’ namespace follows some standards for data types”). Instead of soap, we could have used “SOAP-ENV”, “env”, “s” as well as “mynameisjoe”. The important thing here is only to declare the namespace.
Now let’s look at a more realistic SOAP request with HTTP headers and with a different namespace for the envelope, let’s say a mere “s” as used for the Flickr API. The Header element being optional, we won’t use it here:
POST /soap HTTP/1.1
Host: api.community.com
User-agent: script
Content-type: text/xml
Content-length: 332
<?xml version="1.0"?>
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
s:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<s:Body>
<a:GetMembersList xmlns:a="http://api.community.com/soap">
<age>23</age>
<city>Indianapolis</city>
</a:GetMembersList>
</s:Body>
</s:Envelope>
Note: as you can see, the HTTP headers must have a Host, a User-agent and a Content-type set to text/xml. Now look inside the Body element: what lies there is application-specific data which has to be identified using a different namespace (here we used the SOAP API’s entry point of website community.com). Developers have complete freedom to define what goes inside. Here we chose namespace “a” for all this application-specific data and we described which method had to be called (i.e. GetMembersList) along with parameters age and city.
So far we have seen the basic structure of a SOAP request. Now here is what the SOAP response could look like:
HTTP/1.1 200 OK
Content-type: text/xml
Content-length: 391
<?xml version="1.0"?>
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
s:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<s:Body>
<a:GetMembersListResponse xmlns:a="http://api.community.com/soap">
<members>
<member>Anna</member>
<member>Lisa</member>
</members>
</a:GetMembersListResponse>
</s:Body>
</s:Envelope>
Note: few things have changed in the response. The method name has changed (following the usual convention of appending “Response” to the request’s method name) and the appication-specific data has changed too (it now returns the names of the two members aged 23 and living in Indianapolis). Apart from that, all the namespaces and definition thing remains the same.
Keep in mind that SOAP is all about abstraction and that its complexity is the price for its flexibility. For example, we chose to design the application-specific data inside the first childnode (by calling it a:GetMembersList) but we could have decided as well to specify it along with the data in the following way (the Flickr way):
<a:Request xmlns:a="http://api.community.com/soap">
<method>GetMembersList</method>
<members>
<member>Anna</member>
<member>Lisa</member>
</members>
</a:Request>
In the request example above, we did not specify data types for the parameters we sent along with the request. Without going too much into details, here is the way to specify that <age> is an integer and <city> a string:
POST /soap HTTP/1.1
Host: api.community.com
User-agent: script
Content-type: text/xml
Content-length: 482
<?xml version="1.0"?>
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
s:encodingStyle="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
<s:Body>
<a:GetMembersList xmlns:a="http://api.community.com/soap">
<age xsi:type="xsd:int">23</age>
<city xsi:type="xsd:string">Indianapolis</city>
</a:GetMembersList>
</s:Body>
</s:Envelope>
Note: as you can see we need two more specifications defined as attributes of the Envelope tag. First we need to defined the namespace for XML Schema Instance and then the namespace for XML Schema Datatypes, and then we have to add the corresponding attributes to the <age> and <city> tags (the latter step being quite self-explanatory).
That’s it for this introduction to SOAP. So.. hot or not?
In many cases, SOAP is just bloated XML-RPC. If you can stick to XML-RPC then do it; no need to start using SOAP. On the other hand, if you want to expand the reach of your API or if you need very specific data types for your requests and responses, then go for SOAP. The final choice usually depends on the available libraries: as SOAP is more complex to manipulate, using a good library becomes more important than for XML-RPC where you can go down to making your PHP script directly spit the XML.
(go to Part 6: Web APIs strategy)


1