There are a lot of useful SOAP Web Services. Whether it is a simple zip code lookup service, or a more complex order entry system, a well-implemented SOAP Web Service can make machine to machine communication very reliable, efficient, and best of all, easy.
However, there are also a lot of poorly-implemented SOAP Web Services, and they can cause more problems than they intend to solve. This is the first in a series of articles that attempt to expose some of the more common mistakes and misunderstandings people make when implementing a SOAP Web Service.
SOAP Worst Practice #1: Non-XML Content
One of the main reasons to create a SOAP Web Service over a REST one is that SOAP provides a standardized method to publish the message format for your service. The message is in XML, and its structure is defined in the WSDL, or Web Service Definition Language. If you have an XML document that you want to transfer, embed its format in the WSDL and any consumer will be able to know the format to send to it.
But, if you have non-XML data to transfer, SOAP is probably not your best choice. I’ve seen services where all they contain in their message is an element that takes a base64 encoded content. There is really no benefit to using SOAP in this instance. You’re going through all the trouble to set up the WSDL to define the format, and then just saying “pass any blob of data here.” There is no way to enforce the format inside the blob, thus throwing out the main benefit of SOAP.
If you find yourself doing this, consider using a REST service instead. REST does not define a format for the data content. It also allows you to send any data without doing any encoding on it, just by passing it as the message body with the correct content-type specified.
I admit, that is somewhat of an extreme example. Most people would realize the problem there and decide against using SOAP. More commonly, the problem is that only part of the message is actually non-XML.
An example of this is the PostalMethods service we described in earlier articles. It takes some parameters as XML, but the payload must be base64 encoded and inserted into an element. This is not necessarily bad, but it is also not the best. It causes the consumer to have to do the encoding, and encoded data is also quite bloated compared to the original data. A better solution to this would be to make use of the SOAP Attachments feature, as Matt suggested. Even better, in my opinion, would be to use a REST service instead, using the HTTP Headers and/or Query Parameters to specify the bits of data, and passing the payload as the message body with the appropriate content-type. In fact, they do provide a REST service, however it still takes the payload as a base64 encoded string, so it is not actually much of an improvement.
Another example is a text graphic generator. (WSDL available here) It takes a string and generates a graphical image of it using the specified font, size, etc. This service takes XML as the input, and then returns the image as a base64 encoded GIF image. Again, the same solutions could be applied here for a better implementation. Either return it as a SOAP Attachment, or as the REST response body using the correct content-type. The latter has the added benefit of being able to be called from a web browser, which will just display the image directly. To demonstrate this point, I wrote a little REST wrapper for this service that can be called just using your web browser here.
So, if you have all XML content to be transferred, SOAP is probably your best bet. If there is some non-XML, or possibly no XML at all, it would probably be better to use REST instead.