In an unfortunate event few months back, I lost most of part from my learning notes (that’s what I call the collection). However I noticed one of my document which I wanted to print left in my pd, my learning notes on WSDL for operational web service. Which I created during my training course on SOA by www.javapassion.com. So here I am making these fortunate notes eternal.
So let’s start this lengthy post, which I may cut short later when get time to review.
A web-service is a service which has Programmatic Interfaces exposed over Internet for app. to app. communication. WSDL is the way to define the web service interface for SOAP binding.
WSDL
The key value proposition of WSDL as a standard description of web service is it enables automation of communication details in app. to app. communication. That is, machines can figure out from WSDL document what services are available and how to invoke them without manual pre-arrangement or preconfiguration between the two.
Please also note WSDL’s limitation as well. It defines only the low-level aspects of a web service. That is, it does not specify the high-level business collaboration semantics. Again, this is where ebXML business process and partner profile concept can be very useful.
Under WSDL, a Web service is described as a set of communication endpoints that are capable of exchanging messages. These communication endpoints are called ports. An endpoint is made of two parts:
- 1. Abstract definitions of operations and messages
- 2. Concrete binding to networking protocol (and corresponding endpoint address) and message encoding. One concrete example of network protocol is SOAP over HTTP.
The whole idea of this separation of abstract definitions from concrete binding is to allow the reuse of abstraction definitions regardless of present or future network protocols.
WSDL Elements: WSDL specification defines 7 element types.
1. Types: Data type definitions, used to describe exchanged messages
2. Message: Abstract, typed definitions of data being exchanged
3. Operation: Abstract description of an action. Refers to an input and/or output messages
4. Port Type: Collection of operations, Abstract definition of a service
5. Binding: Concrete protocol and data format (encoding) for a particular Port type
- Protocol examples: SOAP 1.1 over HTTP or SOAP over SMTP
- Encoding examples: SOAP encoding, RDF encoding
6. Port: Defines a single communication endpoint
- Endpoint address for binding
- URL for HTTP, email address for SMTP
7. Service: Aggregate set of related ports
WSDL Syntax: The grammar for a WSDL is as below
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl"
targetNamespace="your namespace here"
xmlns:tns="your namespace here"
xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap">
<wsdl:types>
<xs:schema targetNamespace="your namespace here (could be another) "
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
<!-- Define types and possibly elements here -->
</schema>
</wsdl:types>
<wsdl:message name="some operation input">
<!-- part(s) here -->
</wsdl:message>
<wsdl:message name="some operation output">
<!-- part(s) here -->
</wsdl:message>
<wsdl:portType name="your type name">
<!-- define operations here in terms of their messages -->
</wsdl:portType>
<wsdl:binding name="your binding name" type="tns:port type name above">
<!-- define style and transport in general and use per operation -->
</wsdl:binding>
<wsdl:service>
<!-- define a port using the above binding and a URL -->
</wsdl:service>
</wsdl:definitions>
Types of Operations
1. One-way: The endpoint receives a message
<operation name=”submitPurchase”>
<input message=”purchase”/>
</operation>
2. Request/response: The endpoint receives a message, and sends a correlated message
<operation name=”submitPurchase”>
<input message=”purchase”/>
<output message=”confirmation”/>
</operation>
<operation name=”submitPurchase”>
<input message=”purchase”/>
<output message=”confirmation”/>
<fault message=”faultMessage”/>
</operation>
3. Notification: The endpoint sends a message
<operation name=”deliveryStatus”>
<output message=”trackingInformation”/>
</operation>
4. Solicit/response: The endpoint sends a message, and receives a correlated message
<operation name=”clientQuery”>
<output message=”bandwidthRequest”/>
<input message=”bandwidthInfo”/>
<fault message=”faultMessage”/>
</operation>
Authoring Style Recommendation
Stockquote example Schema and WSDL:
A. stockquote.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://example.com/stockquote/schemas"
xmlns="http://www.w3.org/2000/10/XMLSchema">
<element name="TradePriceRequest">
<complexType>
<all>
<element name="tickerSymbol" type="string" />
</all>
</complexType>
</element>
<element name="TradePrice">
<complexType>
<all>
<element name="price" type="float" />
</all>
</complexType>
</element>
</schema>
B. stockquote.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="StockQuote"
targetNamespace="http://example.com/stockquote/definitions" xmlns:tns="http://example.com/stockquote/definitions"
xmlns:xsd1="http://example.com/stockquote/schemas" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<import namespace="http://example.com/stockquote/schemas"
location="http://example.com/stockquote/stockquote.xsd" />
<message name="GetLastTradePriceInput">
<part name="body" element="xsd1:TradePriceRequest" />
</message>
<message name="GetLastTradePriceOutput">
<part name="body" element="xsd1:TradePrice" />
</message>
<portType name="StockQuotePortType">
<operation name="GetLastTradePrice">
<input message="tns:GetLastTradePriceInput" />
<output message="tns:GetLastTradePriceOutput" />
</operation>
</portType>
</definitions>
C. stockquoteservice.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="StockQuote" targetNamespace="http://example.com/stockquote/service"
xmlns:tns="http://example.com/stockquote/service" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:defs="http://example.com/stockquote/definitions" xmlns="http://schemas.xmlsoap.org/wsdl/">
<import namespace="http://example.com/stockquote/definitions"
location="http://example.com/stockquote/stockquote.wsdl" />
<binding name="StockQuoteSoapBinding" type="defs:StockQuotePortType">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="GetLastTradePrice">
<soap:operation soapAction="http://example.com/GetLastTradePrice" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="StockQuoteService">
<documentation>My first service</documentation>
<port name="StockQuotePort" binding="tns:StockQuoteBinding">
<soap:address location="http://example.com/stockquote" />
</port>
</service>
</definitions>
Binding Element: A binding defines message format and protocol details for operations and messages defined by a particular portType. There may be any number of bindings for a given portType.
-
Defines protocol details and message format for operations and messages defined by a particular portType
-
Specify one protocol out of
– SOAP (SOAP over HTTP, SOAP over SMTP)
– HTTP GET/POST
- Provides extensibility mechanism
– Can includes binding extensibility elements
– Binding extensibility elements are used to specify the concrete grammar
Binding Element Syntax: The grammar for a binding is as below.
<wsdl:definitions .... >
...
<wsdl:binding name="nmtoken" type="qname"> *
<-- extensibility element per binding --> *
<wsdl:operation name="nmtoken"> *
<-- extensibility element per operation --> *
<wsdl:input name="nmtoken"? > ?
<-- extensibility element per input -->
</wsdl:input>
<wsdl:output name="nmtoken"? > ?
<-- extensibility element per output --> *
</wsdl:output>
<wsdl:fault name="nmtoken"> *
<-- extensibility element per fault --> *
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>
SOAP Binding Extension: WSDL includes a binding for SOAP 1.1 endpoints, which supports the specification of the following protocol specific information:
-
An indication that a binding is bound to the SOAP 1.1 protocol
-
A way of specifying an address for a SOAP endpoint.
-
The URI for the SOAPAction HTTP header for the HTTP binding of SOAP
-
A list of definitions for Headers that are transmitted as part of the SOAP Envelope
This binding grammar it is not an exhaustive specification since the set of SOAP bindings is evolving. Nothing precludes additional SOAP bindings to be derived from portions of this grammar. For example:
-
SOAP bindings that do not employ a URI addressing scheme may substitute another addressing scheme by replacing the soap:address element defined in section 3.8.
-
SOAP bindings that do not require a SOAPAction omit the soapAction attribute defined in section 3.4.
SOAP Binding Extensions Syntax: The SOAP Binding extends WSDL with the various extension elements shown below highlighted.
<definitions ....>
<binding ....>
<soap:binding style="rpc|document" transport="uri">
<operation ....>
<soap:operation soapAction="uri"? style="rpc|document" ?>?
<input>
<soap:body parts="nmtokens"? use="literal|encoded"
encodingStyle="uri-list"? namespace="uri" ?>
<soap:header message="qname" part="nmtoken" use="literal|encoded"
encodingStyle="uri-list"? namespace="uri"?>*
<soap:headerfault message="qname" part="nmtoken"
use="literal|encoded" encodingStyle="uri-list"? namespace="uri"? />*
<soap:header>
</input>
<output>
<soap:body parts="nmtokens" ? use="literal|encoded"
encodingStyle="uri-list" ? namespace="uri" ?>
<soap:header message="qname" part="nmtoken" use="literal|encoded"
encodingStyle="uri-list" ? namespace="uri" ?>*
<soap:headerfault message="qname" part="nmtoken"
use="literal|encoded" encodingStyle="uri-list" ? namespace="uri" ? />*
<soap:header>
</output>
<fault>*
<soap:fault name="nmtoken" use="literal|encoded" encodingStyle="uri-list" ? namespace="uri" ?>
</fault>
</operation>
</binding>
<port ....>
<soap:address location="uri" />
</port>
</definitions>
soap:binding:- The soap:binding element MUST be present when using the SOAP binding. The purpose of the SOAP binding element is to signify that the binding is bound to the SOAP protocol format: Envelope, Header and Body. This element makes no claims as to the encoding or format of the message
<definitions ....>
<binding ....>
<soap:binding transport="uri" ? style="rpc|document" ?>
</binding>
</definitions>
1. style attribute applies to each contained operation (default: document) unless it is overidden by operation specific style attribute
2. transport attribute indicates which transport to use
– http://schemas.xmlsoap.org/soap/http (for HTTP)
– http://schemas.xmlsoap.org/soap/smtp (for SMTP)
soap:operation:
<definitions ....>
<binding ....>
<operation ....>
<soap:operation soapAction="uri" ? style="rpc|document" ?>?
</operation>
</binding>
</definitions>
1. style attribute indicates whether the operation is RPCoriented (messages containing parameters and return values) or document-oriented (message containing document(s))
– Affects the way in which the Body of the SOAP message is constructed on the wire.
2. soapAction attribute specifies the value of the SOAPAction header for this operation. This URI value should be used directly as the value for the SOAPAction header; no attempt should be made to make a relative URI value absolute when making the request.
soap:body: The binding element provides information on how to assemble the different message parts inside the Body element of the SOAP message. The element is used in both RPC-oriented and document-oriented messages, but the style of the enclosing operation has important effects on how the Body section is structured:
<definitions ....>
<binding ....>
<operation ....>
<input>
<soap:body parts="nmtokens" ? use="literal|encoded" ?
encodingStyle="uri-list" ? namespace="uri" ?>
</input>
<output>
<soap:body parts="nmtokens" ? use="literal|encoded" ?
encodingStyle="uri-list" ? namespace="uri" ?>
</output>
</operation>
</binding>
</definitions>
soap:body for RPC style: If the operation style is rpc, each part is a parameter or a return value and appears inside a wrapper element within the body. The wrapper element is named identically to the operation name and its namespace is the value of the namespace attribute.
-
Each message part (parameter) appears under the wrapper, represented by an accessor named identically to the corresponding parameter of the call.
-
Parts are arranged in the same order as the parameters of the call.
WSDL document:
-
The operation name of WSDL document is used to name the wrapper element (immediate child element under element)
-
Name of the wrapper element is a method
Each part is a parameter or a return value and appears inside a wrapper element within the
<soap:Body>
SOAP message:
-
Contents of the Body are formatted as a struct
-
Parts are arranged in the same order as the parameters of the call
Example: MyHelloServiceRpcLiteral.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="urn:Foo" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="MyHelloService"
targetNamespace="urn:Foo">
<types />
<message name="HelloIF_sayHello">
<part name="String_1" type="xsd:string" />
<part name="Integer_2" type="xsd:int" /> </message>
<message name="HelloIF_sayHelloResponse">
<part name="result" type="xsd:string" /> </message>
<portType name="HelloIF">
<operation name="sayHello" parameterOrder="String_1 Integer_2">
<input message="tns:HelloIF_sayHello" />
<output message="tns:HelloIF_sayHelloResponse" />
</operation>
</portType>
<binding name="HelloIFBinding" type="tns:HelloIF">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="rpc" />
<operation name="sayHello">
<input>
<soap:body use="literal" namespace="urn:Foo" />
</input>
<output>
<soap:body use="literal" namespace="urn:Foo" />
</output>
<soap:operation soapAction="" />
</operation>
</binding>
<service name="MyHelloService">
<port name="HelloIFPort" binding="tns:HelloIFBinding">
<soap:address xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
location="http://localhost:8080/hello-jaxrpc/hello" />
</port>
</service>
</definitions>
This is the WSDL document for the helloservice Web service in which RPC style and Literal data format are used.
As for the data format, the literal data format means that each part references to a schema definition, which could be a simple type such as xsd:string as it is the case for this example or a complex type.
SOAP Request Message: RPC, Literal: This is actual SOAP message that reflects RPC style and literal data format.
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:n="urn:Foo"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<n:sayHello>
<String_1>MyRpcLiteralMessage</String_1>
<Integer_2>79</Integer_2>
</n:sayHello>
</soap:Body>
</soap:Envelope>
SOAP Response Message: RPC, Literal:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:Foo">
<env:Body>
<ns0:sayHelloResponse>
<result>Hello MyRpcLiteralMessage79</result>
</ns0:sayHelloResponse>
</env:Body>
</env:Envelope>
SOAP:body for Document style: For document stype, each message has a single element. And the element attribute of the element defines schema definition of XML document fragment.
WSDL document:
● Each <message> has single <part> element
● The element attribute of <part> refers to schema definition of XML document fragment, which is defined inside <types>
SOAP message:
● SOAP Body element contains an XML document fragment (document)
● E.g.) Purchase order XML document fragment
● There are no wrappers
Example: MyHelloServiceDocLiteral.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="urn:Foo" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="MyHelloService"
targetNamespace="urn:Foo">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:soap11-enc="http://schemas.xmlsoap.org soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:Foo">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<complexType name="sayHello">
<sequence>
<element name="String_1" type="string" nillable="true" />
<element name="Integer_2" type="int" nillable="true" />
</sequence>
</complexType>
<complexType name="sayHelloResponse">
<sequence>
<element name="result" type="string" nillable="true" />
</sequence>
</complexType>
<element name="sayHello" type="tns:sayHello" />
<element name="sayHelloResponse" type="tns:sayHelloResponse" />
</schema>
</types>
<message name="HelloIF_sayHello">
<part name="parameters" element="tns:sayHello" />
</message>
<message name="HelloIF_sayHelloResponse">
<part name="result" element="tns:sayHelloResponse" />
</message>
</definitions>
This is the WSDL document for the helloservice Web service in which Document style and Literal data format are used.
Please note that there two complexType definitions, “sayHello” and “sayHelloResponse” within the types element. These two definitions will be used to reflect the XML document fragments, one in the request and the other in the response SOAP messages.
SOAP Request Message: Doc, Literal: This is actual SOAP message that reflects document style and literal data format.
Here the tns:sayHello element (along with its child elements) reflects a XML document fragment whose type is defined by the XML schema definitions.
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tns="urn:Foo" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<tns:sayHello>
<String_1>MyDocLiteralMessage</String_1>
<Integer_2>78</Integer_2>
</tns:sayHello>
</soap:Body>
</soap:Envelope>
SOAP Response Message: Doc, Literal:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:Foo">
<env:Body>
<ns0:sayHelloResponse>
<result>Hello MyDocLiteralMessage78</result>
</ns0:sayHelloResponse>
</env:Body>
</env:Envelope>
use attribute of soap:body: use=”literal|encoded”
-
literal
– parts define the concrete schema of the message
– XML document fragment can be validated against its XML schema
-
encoded
– Indicates whether the message parts are encoded using some encoding rules
use=”literal”: Each part references a concrete schema definition using either the element or type attribute (WS-I profile says use element)
-
element attribute
– Document style: the element referenced by the part will appear directly under the Body element
– RPC style: the element referenced by the part will appear under an accessor element named after the message part.
-
type attribute: The type referenced by the part becomes the schema type of the enclosing element
use=”encoded”: Each message part references an abstract type using the type attribute
– abstract types are used to produce a concrete message by applying an encoding specified by the encodingStyle attribute.
– part names, types and value of the namespace attribute are all inputs to the encoding.
Possible Style/Use Combinations
1. style=”rpc” and use=”encoded”
2. style=”rpc” and use=” literal”
3. style=”document” and use=”encoded”
4. style=”document” and use=”literal”
Example: SOAP Binding style=”rpc” use=”encoded” MyHelloServiceRpcEncoded.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="urn:Foo" xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
name="MyHelloService" targetNamespace="urn:Foo">
<types />
<message name="HelloIF_sayHello">
<part name="String_1" type="xsd:string" />
<part name="Integer_2" type="ns2:int" />
</message>
<message name="HelloIF_sayHelloResponse">
<part name="result" type="xsd:string" />
</message>
<portType name="HelloIF">
<operation name="sayHello" parameterOrder="String_1 Integer_2">
<input message="tns:HelloIF_sayHello" />
<output message="tns:HelloIF_sayHelloResponse" />
</operation>
</portType>
<binding name="HelloIFBinding" type="tns:HelloIF">
<operation name="sayHello">
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="urn:Foo" />
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="urn:Foo" />
</output>
<soap:operation soapAction="" />
</operation>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />
</binding>
<service name="MyHelloService">
<port name="HelloIFPort" binding="tns:HelloIFBinding">
<soap:address xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" location="http://localhost:8080/hellojaxrpc/hello" />
</port>
</service>
</definitions>
SOAP Request Message: rpc, encoded:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:n="urn:Foo"
xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/XMLSchema-instance">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<n:sayHello>
<String_1 xsi:type="xs:string">MyRpcEncodingMessage
</String_1>
<Integer_2 xsi:type="ns2 :int">77</Integer_2>
</n:sayHello>
</soap:Body>
</soap:Envelope>
SOAP Response Message: rpc, encoded:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:Foo"
env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:sayHelloResponse>
<result xsi:type="xsd:string">Hello MyRpcEncodingMessage77</result>
</ns0:sayHelloResponse>
</env:Body>
</env:Envelope>
Example: SOAP Binding style=”document” use=”encoded”
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://tempuri.org/" xmlns:types="http://tempuri.org/encodedTypes"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<types:HelloEncodedWorldResponse
xsi:type="types:HelloEncodedWorldResponse">
<HelloEncodedWorldResult href="#id1" />
</types:HelloEncodedWorldResponse>
<types:MethodDuration id="id1" xsi:type="types:MethodDuration">
<start xsi:type="xsd:dateTime">dateTime</start>
<end xsi:type="xsd:dateTime">dateTime</end>
<rVal xsi:type="xsd:string">string</rVal>
</types:MethodDuration>
</soap:Body>
</soap:Envelope>