There is an old joke in the distributed computing community: Agents are the wave of the future—and have been for 30 years. It's just that the future hasn't caught up with agents yet.
In a few years, will we joke similarly about SOAP? When reminiscing with colleagues around the water cooler about past technologies that did not, after all, become the wave of the future, will we ask, "Remember SOAP?"
Let me point out that I'm not for or against SOAP: I don't believe in being for or against a technology. But I do believe in using the right tools for a job. SOAP is rapidly becoming the generally accepted protocol for XML- based system-to-system communication. Because several important Web services infrastructures rely on SOAP for XML message transfer, many developers have adopted SOAP as an essential Web service tool.
But is SOAP necessary to build XML-based Web services?
The W3C's Web Services Architecture working group doesn't mandate using SOAP for a Web service. According to the W3C's definition (See Resources):
A Web service is a software system identified by a URI, whose public interfaces and bindings are defined and described using XML. Its definition can be discovered by other software systems. These systems may then interact with the Web service in a manner prescribed by its definition, using XML-based messages conveyed by Internet protocols.
You don't need SOAP to build a system that satisfies that definition: The Web Services Description Language (WSDL) defines and describes a Web service with XML; UDDI (Universal Description, Discovery, and Integration) facilitates service discovery; and XML messages are easily sent between services via HTTP or some other Web protocol.
For many Web services, you need only a combination of XML, HTTP, and an application-specific message protocol. To be sure, SOAP has its uses. But, in my opinion, SOAP's role is overstated in the early stages of a Web service's development. Using SOAP for the wrong tasks can easily hijack a Web service development project, because SOAP introduces a large set of problems that are orthogonal to the challenges of building a Web service. SOAP-related issues tend to consume the majority of the development effort.
The most common purpose of Web services today is to exchange XML data. For instance, more than 200 Web services listed on XMethods (See Resources) share that purpose. The classic examples of a stock quote service, weather service, or postal code lookup service are all about sending an XML query message, and receiving an XML reply. That pattern dominates more complex Web services as well: the UDDI registry service or the Liberty Alliance single sign-on and identity federation Web services are all defined in terms of XML-based query-response message exchanges.
At best, SOAP introduces a level of indirection to such XML message exchanges by embedding an XML message in a SOAP envelope. Since the SOAP envelope can carry metadata about the original XML message, such as processing instructions, the envelope can aid a Web service in processing that message. At worst, SOAP makes it difficult, if not impossible, to verify the validity of an XML message traversing between two Web services.
The example message exchange that illustrates the W3C's SOAP specifications and primer (see Resources) belongs to a travel reservation service. Before considering how a SOAP-embedded reservation message looks, imagine the simplest possible way to design such a service. A minimalist reservation service design would define a set of XML documents, and a choreography—or protocol—of how those messages pass between the service and its client.
Thus, you would have XML messages corresponding to a schedule and price inquiry, a reservation request, a confirmation, and a final itinerary. You can define the structure and possible values of those XML messages with XML schema. And you can define the reservation protocol with XML as well, perhaps using an XML-based Web service choreography language (see Resources).
Perhaps the easiest way to implement such a service is to write a servlet that listens for incoming messages, routes those messages to a message processor component—such as an EJB—and then returns the results to the caller. That Web service implementation works exactly as a Web site. Only, instead of HTML, that service receives and sends XML documents. Figure 1 illustrates that simple implementation.
Figure 1. A SOAPless Web service.
Provided you've already written your business-specific objects—such as the component accessing a flight schedule database—building and deploying a Web service based on that simple design is a breeze. The service uses only standard HTTP, XML, and possibly EJBs. Since you don't have to worry about pretty HTML formatting, developing that Web service likely takes less time than building a Web site with similar functionality.
But Figure 1 is not the Web service design you'll find in many Web service text books. Current technological vogue would have you insert a level of indirection into the system: a SOAP processor or SOAP container. A SOAP container is a component that specializes in processing SOAP messages. Following the directives placed inside the SOAP envelope, as well as in the container's own deployment descriptor, the SOAP processor invokes handlers to process the SOAP message.
SOAP is more general-purpose than the HTTP + XML solution. But, at the end of the day, a SOAP-based Web service simply hands off the processing of incoming messages to an object designed to handle a given message format. Figure 2 depicts a Web service with a SOAP container.
Figure 2. A Web service with SOAP.
Many organizations aiming to develop Web services fall into the trap of choosing Figure 2's architecture over that of Figure 1 when they design their first services. But for simple Web services, a SOAP-based design may add little value over an XML + HTTP-based solution.
Consider the following XML document, representing a request to charge a travel reservation on a credit card:
<?xml version='1.0'?> <reservation> <code> 12345 </code> <o:creditCard xmlns:o="http://mycompany.example.com/financial"> <n:name xmlns:n="http://mycompany.example.com/employees"> John Galt </n:name> <o:number> 123456789099999 </o:number> <o:expiration> 2005-02 </o:expiration> </o:creditCard> </reservation>
Using just HTTP, you could open a socket to a Web service, and submit such a document via a POST operation. A servlet on the receiving end could route the XML message, based on the message's type, to an object that processes a reservation. Finally, the servlet could send back an HTTP response, confirming a reservation. You could write a servlet that performs that functionality in fewer than 20 lines of code, not counting the processing of the XML messages.
With SOAP, you could embed this message inside a SOAP envelope:
<?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2002/12/soap-envelope"> <env:Header> <m:reservationCharge xmlns:m="http://travelcompany.example.org/reservation" env:role="http://www.w3.org/2002/12/soap-envelope/role/next" env:mustUnderstand="true"> <m:reference>12345</m:reference> <m:dateAndTime>2003-03-09T14:00:00.000- 09:00</m:dateAndTime> </m:reservationCharge> </env:Header> <env:Body> <r:reservationCharge xmlns:p="http://travelcompany.example.org/reservation"> <r:code> 12345 </r:code> <o:creditCard xmlns:o="http://mycompany.example.com/financial"> <n:name xmlns:n="http://mycompany.example.com/employees"> John Galt </n:name> <o:number> 123456789099999 </o:number> <o:expiration> 2005-02 </o:expiration> </o:creditCard> </r:reservationCharge> </env:Body> </env:Envelope>
This SOAP message adds a simple header, providing some metadata about the message. When the SOAP message arrives, a SOAP processor looks at the header first, and the header metadata can help the SOAP processor determine what it should do with the body. This type of SOAP message is called a document style message, because it simply embeds an XML document in its
When a processor receives a document-style SOAP message, that processor must still decipher where to route that message. Thus, receiving and processing document-style SOAP messages present almost identical tasks to processing an incoming XML message directly from an HTTP stream. The difference is the added complexity of the SOAP message.
Using SOAP, however, you are not restricted to a document-style message exchange. Instead of modeling your Web service as a series of message exchanges, you can design a Web service as an XML-based API available for remote procedure calls, or XML RPCs. In your Web service client, instead of this code:
reservationServiceSocket.write(reservationPaymentRequest)you could write:
reservationService.chargeReservation(Reservation res, CreditCard card)
An RCP-style SOAP message carries method parameters and return types, and indicates the names of the methods to invoke. The following example, taken from the W3C's SOAP Primer, illustrates a SOAP message intended for remote procedure invocation:
<?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2002/12/soap-envelope"> <env:Header> <t:transaction xmlns:t="http://thirdparty.example.org/transaction" env:encodingStyle="http://example.com/encoding" env:mustUnderstand="true" >5</t:transaction> </env:Header> <env:Body> <m:chargeReservation env:encodingStyle="http://www.w3.org/2002/12/soap-encoding" xmlns:m="http://travelcompany.example.org/"> <m:reservation xmlns:m="http://travelcompany.example.org/reservation"> <m:code>12345</m:code> </m:reservation> <o:creditCard xmlns:o="http://mycompany.example.com/financial"> <n:name xmlns:n="http://mycompany.example.com/employees"> John Galt </n:name> <o:number> 123456789099999 </o:number> <o:expiration> 2005-02 </o:expiration> </o:creditCard> </m:chargeReservation> </env:Body> </env:Envelope>
The response to this RPC input message would be an RPC output message, containing the return values from the invocation (a confirmation, in this case). While the document-style SOAP message imposed no particular order or structure on the SOAP body, the RPC-style SOAP envelope adheres to one of two sets of encoding rules: It may either follow literally an XML schema, or may be encoded with SOAP encoding. The above example follows the SOAP encoding style, as the
encodingStyle attribute shows.
SOAP encoding simplifies serializing complex XML graphs. But because it does not follow an XML schema specific to a method parameter or return message, you can no longer rely on a schema-aware validating parser to ensure data integrity. Thus, while gaining a convenient, RPC-style programming paradigm that serializes complex parameters, you lose some of the XML benefits. If you use literal SOAP encoding, you can rely on schema validation to work, but you pay the price in increased complexity of serializing complex XML documents.
During my day job, I recently developed a Web service client that accesses four different Web service providers. Each service provider is a leader in its field, and its customers rely on the provider for mission-critical data. I estimate that each provider must process tens of thousands of Web service transactions every hour. Each firm implemented its Web service without SOAP, using the architecture depicted in Figure 1. When I asked their architects whether they would eventually support SOAP-based access to their data, they did not at first understand the reason for my inquiry. From their viewpoint, their firms must provide highly reliable, high-throughput data access, and HTTP + XML is all they need to fulfill those requirements. They considered SOAP an unnecessary addition to a system that already worked well.
Intrigued by their resistance to SOAP, I conducted an informal survey of a few, large enterprise IT shops. They were all working on XML-based data access solutions in business-to-business interactions. But, to my surprise, many of them transmitted XML documents via HTTP, without any trace of SOAP encoding. Several IT managers I spoke with commented: If HTTP + XML works so well, why use SOAP?
In my experience, a SOAPless solution works for most simple Web services. And many Web services are simple. If you look at the publicly available Web services list on XMethods, or search a UDDI registry, you will find that most Web services currently provide but a handful of basic functions—retrieving a stock price, obtaining a dictionary word definition, performing a math function, or reserving an airline ticket. All those activities are modeled as simple query-response message exchanges. HTTP was designed as an effortless protocol to handle just such query- response patterns, which is largely the reason for its popularity. Simple Web services can piggyback on HTTP's mature infrastructure and popularity by directly sending business-specific XML messages via HTTP operations without an intermediary protocol.
Of course, there are many Web services that rely on SOAP. The RPC-style SOAP usage seems more popular, but lately some Web services started to define document-style SOAP messages. One reason for that trend may be the need to interoperate between various SOAP implementations: When the SOAP message carries a simple XML document, you don't rely on a specific SOAP implementation's way of encoding that message. But document-style SOAP also meshes with the request/response message nature of many Web services.
You need SOAP when you design your Web service not as a series of message exchanges, but as a Web-accessible API. SOAP, and its various implementations, automate much of the marshalling and unmarshalling of method parameters and return values when invoking that API.
There can be no one "best" way to design a Web service. My take is that simple Web services should be kept simple. I don't see many reasons to build an API consisting of a single method, with that method consuming one parameter and returning a minor value. An API makes sense when interaction with a service is more intricate—for instance, if you must offer alternate ways of obtaining information from a service. In that case, an API affords a richer interface to that Web service. A well-designed API is also easier for programmers to understand than a bunch of XML message exchanges.
But even in the case of a complex service, you would first have to define your parameter and return value XML structures. You may find that you can often define a complex Web service without reference to any specific invocation style, such as socket-based message exchanges (HTTP + XML) or through SOAP. If you design your service with that flexibility in mind, you can start out using simple HTTP, and switch to a SOAP-based implementation as the need arises. You may find that your Web service's clients will be happy with HTTP for quite a while.
One advantage of keeping your Web services simple is that, instead of spending time debugging them, you get to spend more time hanging around the water cooler, chatting about technologies and protocols that, surely, are the wave of the future. Will SOAP be the wave of the future when it comes to Web services? Or will developers eschew its use in favor of simple HTTP-based XML messaging protocols? Let us know what you think on the Artima forums!
Come back Monday, April 14, for the next installment of Frank Sommer's Web Services column. If you'd like to receive a brief weekly email announcing new articles at Artima.com, please subscribe to the Artima Newsletter.
The W3C's definition of a Web service:
The SOAP specifications:
The SOAP Primer:
More information on service choreography languages:
XMethods lists web services publicly available on the internet:
Frank Sommers is an editor with Artima Developer. He is also founder and president of Autospaces, Inc., a company providing collaboration and workflow tools in the financial services industry.