SOAP works well in an informal context. It's as if two friends meet and talk about a cool new Web site using slang and informal lingo. However, these friends couldn't talk as informally to a judge in a courtroom. Saying, "Hey, judge. How's it hanging?" wouldn't go over too well. Likewise, when strangers exchange SOAP messages a formalized approach is required: Web Service Definition Language (WSDL).
A WSDL document has the following five types:
XML types : You can define the XML type of the various elements of the SOAP message. This allows you to verify the correctness of the data sent and/or received.
Message description : A SOAP message is a concatenation of various logical message sections. Consider an individual SOAP message as a chapter in a book and the logical part as a paragraph within the chapter.
Port type : Programmers might think that port means logical device port, but it doesn't. The port type means a combination of input and output messages. If we use a book metaphor, a port is like a part of a book that contains different chapters.
Binding : This defines the specific format of the port type, including things like a protocol or data binding. If we use the book metaphor, a binding is the entire book, including pictures, chapters, etc.
Service : This defines the service, which implies that the Service tag is the entry point and puts everything together for processing.
A WSDL document defines some type of abstract business logic that is associated with a number of SOAP messages. WSDL is the metadata and object-oriented capabilities of Web Services.
The first step of the WSDL definition process is to define the various XML types that make up the SOAP message. This means describing the SOAP message using either an encoding or an XML Schema (the preferred way). A sample WSDL-type declaration that describes the data types in Listing 10.2 is shown in Listing 10.7.
<types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.devspace.com/2002/1/math" elementFormDefault="qualified"> <xs:element name=" add"> <xs:complexType> <xs:sequence> <xs:element name="num" ref="num" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name=" math" type="xs:anyURI" use="required"/> </xs:complexType> </xs:element> <xs:element name=" num"> <xs:simpleType> <xs:restriction base="xs:byte"> <xs:enumeration value="1"/> <xs:enumeration value="2"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:schema> </types>
In Listing 10.7, the XML element types defines the section where the data types of the SOAP message are defined. The types are defined using the XML tag schema which means all of the embedded XML tags are XML Schema- related items.
Once you've defined the types, you need to define the message, which defines individual SOAP messages that are sent. Note that a message is a one-way message. Jumping a bit ahead of ourselves , an RPC-type SOAP call would involve two messages: from sender to receiver and from receiver to sender. Listing 10.8 is a sample definition of two SOAP messages.
<wsdl:message name="msgAdd"> <wsdl:part name="main" element="mathxsd:add"/> </wsdl:message> <wsdl:message name="msgAddResponse"> <wsdl:part name="main" element="mathxsd:addResponse"/> </wsdl:message>
In Listing 10.8, the XML tag message identifies a message and has as a child element the XML tag part The XML tag part has two attributes: name and element The attribute name defines the name of the SOAP message. The attribute element references an XML element that represents the message contents that are sent. Note that in most likelihood , the attribute element references a type defined in the XML types section. Listing 10.8 only has one child XML tag part However, in a more complicated message-based SOAP message, there could be multiple part XML tags.
A WSDL port type has absolutely nothing to do with a socket port. A WSDL port type is a way of describing an interaction between the sender and receiver of the SOAP message. The SOAP specification outlines specific ways of doing a message exchange. A response to a message just happens to be another message exchange. Using WSDL, you can define exactly what will be sent and received. This is very important; consider the case of sending a SOAP message using SMTP. With SMTP, you can't get an answer right away and hence a waiting SOAP sender will wait indefinitely. If you use WSDL, the infrastructure can determine if a response will be sent, and when. However, do not consider the port type as a physical definition of a SOAP message exchange. The port type defines an abstract message exchange mechanism. The specifics are defined in the bindings, which we will discuss later in this chapter.
In the WSDL messages, the messages are used to reference a conversation, as shown in Listing 10.9.
<wsdl:portType> <wsdl:operation name="portAddingNumbers"> <wsdl:input name="Adding" message="msgAdd"/> <wsdl:output name="Result" message="msgAddResponse"/> </wsdl:operation> </wsdl:portType >
In Listing 10.9, the port is defined using the XML tag portType . Within the XML tag portType are one or multiple child operation XML tags. Each XML tag operation defines a SOAP conversation, which is defined using child input and output XML tags. An input message is a message sent from sender to receiver. An output is a message sent from receiver to sender. The XML tags input and output have two attributes: name and message . The attribute name defines the message type. The attribute message references a message from the WSDL message section. In theory, WSDL could define a whole host of conversations that have multiple inputs and multiple outputs. However, WSDL defines the following four logical conversation types (note that the XML child tag combinations of input and output are defined in the brackets):
One Way Operation (input) : The sender sends a SOAP message to the receiver and does not expect a response.
Request Response Operation (input-output) : The sender sends a SOAP message to the receiver, and the receiver will send a response to the message.
Solicit Response Operation (output) : The receiver sends a SOAP message to the sender, and the sender will send a response. If this sounds confusing, consider this nothing more than an asynchronous callback using SOAP.
Notification Operation (output - input) : The receiver sends a SOAP message to the sender, and the receiver does not expect an answer. This could also be called a " targeted broadcast" in SOAP terms.
Listing 10.9 is a sample Request Response-type conversation.
Binding is a bit more complicated to understand than defining messages or types in a WSDL file because a binding mixes together multiple XML elements that have nothing to do with each other. Binding is a generic way of defining an actual exchange of messages. It is important to remember that the exchange of messages may or may not be SOAP related. For example, the messages that are exchanged could be HTTP based, or even XML RPC based. In the simplest case, a binding is defined in Listing 10.10.
<binding name="BindingAddition" type="portAddingNumbers"> <operation name="AddSomeNumbers"> <input message="add"> </input> </operation> </binding>
Listing 10.10 looks very similar to Listing 10.9, which defines a port. This occurs because the binding is fine-tuning the conversation. You can overload and override the individual conversations. Listing 10.11 is a typical binding definition.
<binding name="bindingAddition" type="portAddingNumbers"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="AddSomeNumbers"> <soap:operation soapAction="http://www.devspace.com/add"/> <input message="add"> <soap:body use="encoded" namespace="http://example.com/stockquote" encodingStyle="http://schemas.xmlsoap.org/soap/ encoding/"/> </input> </operation> </binding>
In Listing 10.11, the elements associated with the namespace soap have been added. The added elements are used to define the various SOAP-specific attributes that relate to a binding. Listing 10.11 is saying that there is a conversation, but it is using SOAP as the messaging technique. Specifically, the XML tag soap:binding is saying that an RPC-type conversation is desired. The XML tag soap:body is saying that the SOAP content is SOAP encoded.
The last item to define in a WSDL file is the service itself. The service provides the entry point to the WSDL file. From the service definition you can figure out what is being defined and how it is to be used. Listing 10.12 shows how to define a service for the bindings defined in the previous section.
<service name="MathService"> <documentation>Want to add numbers?Here it is</documentation> <port name="AddNumbersPort" binding="tns:bindingAddition"> <soap:address location="http://www.devspace.com.com/addnums"/> </port> </service>
In Listing 10.12, the service is defined by the service XML tag, with the name attribute being a unique name to identify the Web Service. Newly used is the documentation XML tag. We have avoided using this tag, but it is optional with every major WSDL item type. The documentation tag makes it possible to provide generic documentation that can be displayed using a tool. Don't confuse the documentation tag with the XML comment tag. The documentation tag is for application processing and display. Within the WSDL service tag is the port tag. The port tag is responsible for providing a physical binding to the binding defined by bindingAddition . In our binding example, SOAP and HTTP were used, but the address where the service was located was not provided. The SOAP address_location tag provides the physical address. Again, this is an abstraction to make it simpler to separate and reuse various WSDL definitions.
The individual pieces of the WSDL have been defined, so now it is time to put everything together into one WSDL file, as shown in Listing 10.13.
<definitions name="MyAdditionExample" targetnamespace="http://www.devspace.com/addition.wsdl" xmlns:tns=" http://www.devspace.com/addition.wsdl" xmlns:xsd="http://www.w3.org/2000/10/XMLSchema" xmlns:xsd=" http://www.devspace.com/2002/1/math" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> ...<!Put everything into here> </definitions>
We can simply cut and paste the individual elements that were defined into the area where the XML comment says "Put everything into here." The only issue is to make sure that the namespaces are correct. WSDL and SOAP are very namespace-heavy and hence require careful attention.
To keep things simple, you should cut and paste the namespaces defined in Listing 10.13 and make appropriate changes for the namespaces targnetnamespace , tns , and xsd1 . The changes in each namespace are defined by the following list:
targetnamespace : This defines the namespace of your WSDL file locally, and hence should be a unique identifier.
xmlns:tns : This is the same namespace of the targetnamespace except that the namespace is being assigned to a prefix.
xmlns:xsd : This is the namespace definition of your types defined in terms of a Schema file, or it should be the same namespace as defined in the types section of the WSDL file.
Another thing you should remember when creating WSDL files is to stick with the same namespace prefixes. This makes it simpler to create and debug the various WSDL files.
To keep smaller WSDL files and make it possible to reuse different files, you can import sections into your WSDL file (so that you don't have to recreate them). An example of importing XML content into a WSDL is Listing 10.14.
<definitions name="MyAdditionExample"> <import namespace=" http://www.devspace.com/2002/1/math" location="http://www.devspace.com/math/math.xsd"/> ... </definitions>
One last question to ask yourself when you're working with WSDL: do you create WSDL files by hand or do you have a tool to generate them? The answer is that it doesn't matter. WSDL files are going to created once and kept forever. The one problem with Web Services is that once deployed, they cannot be changed. Imagine a popular SOAP service where changing the WSDL once could cause all clients to crash. A WSDL file has to be defined once, and you need to take great care so that it is defined properly.