Sponsored Link •
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
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.