Figure 1: Resources and services
This architecture makes it possible for any consumer with XML support to integrate with Web service applications. However, in order to accomplish this, consumers must determine the precise XML interface along with other miscellaneous message details a priori. XML Schema can partially fill this need because it allows developers to describe the structure of XML messages. XML Schema alone, however, can't describe the additional details involved in communicating with a Web service. A schema definition simply tells you what XML messages may be used but not how they relate to each other. For example, if there's an XML element named Add and another named AddResponse, it's likely they're related to each other but there's no way to indicate that in the schema. Hence, in addition to being aware of the messages, consumers must also be aware of the possible message exchanges supported by the Web service (e.g., if you send an Add message, you get an AddResponse message back).
A message exchange is also referred to as an operation. Operations are what consumers care about most since they're the focal point of interacting with the service (see Figure 2). Whenever I approach a new Web service, I first inspect its list of supported operations to get an overall feel for what it offers.
Figure 2: Messages and operations
It's common for developers to group related operations into interfaces. Consumers must be aware of these groupings since it impacts the way they write their code. This is especially important to developers working with Web services in object-oriented environments since the XML interfaces can map to programmatic interfaces (or abstract classes) in their language of choice. Consumers must also know what communication protocol to use for sending messages to the service, along with the specific mechanics involved in using the given protocol such as the use of commands, headers, and error codes. A binding specifies the concrete details of what goes on the wire by outlining how to use an interface with a particular communication protocol. A binding also influences the way abstract messages are encoded on the wire by specifying the style of service (document vs. RPC) and the encoding mechanism (literal vs. encoded). Check out Understanding SOAP for more background on these concepts.
A service can support multiple bindings for a given interface, but each binding should be accessible at a unique address identified by a URI, also referred to as a Web service endpoint (see Figure 3).
Figure 3: Interfaces and bindings
Consumers must discover all of the details described above before they can interact with a Web service. The Web Services Description Language (WSDL) provides an XML grammar for describing these details. WSDL picks up where XML Schema left off by providing a way to group messages into operations and operations into interfaces. It also provides a way to define bindings for each interface and protocol combination along with the endpoint address for each one. A complete WSDL definition contains all of the information necessary to invoke a Web service. Developers that want to make it easy for others to access their services should make WSDL definitions available.WSDL plays an important role in the overall Web services architecture since it describes the complete contract for application communication (similar to the role of IDL in the DCOM architecture). Although other techniques exist for describing Web services, the WS-I Basic Profile Version 1.0 mandates the use of WSDL and XML Schema (see Figure 4) for describing Web services. This helps ensure interoperability at the service description layer.
Figure 4: WS-I Basic Profile 1.0 technologies
Since WSDL is a machine-readable language (e.g., it's just an XML file), tools and infrastructure can be easily built around it. Today developers can use WSDL definitions to generate code that knows precisely how to interact with the Web service it describes. This type of code generation hides the tedious details involved in sending and receiving SOAP messages over different protocols and makes Web services approachable by the masses. The Microsoft® .NET Framework comes with a command-line utility named wsdl.exe that generates classes from WSDL definitions. Wsdl.exe can generate one class for consuming the service and another for implementing the service. (Apache Axis comes with a similar utility named WSDL2Java that performs the same function for Java classes.) Classes generated from the same WSDL definition should be able to communicate with each other through the WSDL-provided interfaces, regardless of the programming languages in use (see Figure 5).
Figure 5: WSDL and code generation
WSDL 1.1 is considered the de-facto standard today because of it's industry-wide support. Most Web services toolkits support WSDL 1.1, but there have been some interoperability problems across the different implementations. Many developers believe that the extensive flexibility of WSDL (and the resulting complexity) is the fundamental source of these problems. The WS-I has helped resolve some of these issues by encouraging developers to use certain parts of the specification and discouraging them from using others. The W3C is actively working on the next "official" version of WSDL, WSDL 1.2, but it's currently only a Working Draft and not supported by the mainstream toolkits, if any. The remainder of this article discusses the details of a WSDL 1.1 definition and highlights some of the WS-I basic profile suggestions along the way.
WSDL Basics
A WSDL definition is an XML document with a root definition element from the http://schemas.xmlsoap.org/wsdl/ namespace. The entire WSDL schema is available at http://schemas.xmlsoap.org/wsdl/ for your reference. The definitions element may contain several other elements including types, message, portType, binding, and service, all of which come from the http://schemas.xmlsoap.org/wsdl/ namespace. The following illustrates the basic structure of a WSDL definition:<!-- WSDL definition structure --> <definitions name="MathService" targetNamespace="http://example.org/math/" xmlns="http://schemas.xmlsoap.org/wsdl/" > <!-- abstract definitions --> <types> ... <message> ... <portType> ... <!-- concrete definitions --> <binding> ... <service> ... </definition>
The first three elements (types, message, and portType) are all abstract definitions of the Web service interface. These elements constitute the programmatic interface that you typically interface with in your code. The last two elements (binding and service) describe the concrete details of how the abstract interface maps to messages on the wire. These details are typically handled by the underlying infrastructure, not by your application code. Table 1 provides brief definitions for each of these core WSDL elements and the remaining sections discuss them in more detail.
Table 1. WSDL Elements
Element Name | Description |
types | A container for abstract type definitions defined using XML Schema |
message | A definition of an abstract message that may consist of multiple parts, each part may be of a different type |
portType | An abstract set of operations supported by one or more endpoints (commonly known as an interface); operations are defined by an exchange of messages |
binding | A concrete protocol and data format specification for a particular portType |
service | A collection of related endpoints, where an endpoint is defined as a combination of a binding and an address (URI) |
Types
The WSDL types element is a container for XML Schema type definitions. The type definitions you place here are referenced from higher-level message definitions in order to define the structural details of the message. Officially, WSDL 1.1 allows the use of any type definition language, although it strongly encourages the use of XML Schema and treats it as its intrinsic type system. The WS-I enforces this by mandating the use of XML Schema in the Basic Profile 1.0.The types element contains zero or more schema elements from the http://www.w3.org/2001/XMLSchema namespace. The basic structure of the types element (with namespaces omitted) is as follows (* means zero or more):
<definitions .... > <types> <xsd:schema .... />* </types> </definitions>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:y="http://example.org/math/" xmlns:ns="http://example.org/math/types/" targetNamespace="http://example.org/math/" > <types> <xs:schema targetNamespace="http://example.org/math/types/" xmlns="http://example.org/math/types/" > <xs:complexType name="MathInput"> <xs:sequence> <xs:element name="x" type="xs:double"/> <xs:element name="y" type="xs:double"/> </xs:sequence> </xs:complexType> <xs:complexType name="MathOutput"> <xs:sequence> <xs:element name="result" type="xs:double"/> </xs:sequence> </xs:complexType> <xs:element name="Add" type="MathInput"/> <xs:element name="AddResponse" type="MathOutput"/> <xs:element name="Subtract" type="MathInput"/> <xs:element name="SubtractResponse" type="MathOutput"/> <xs:element name="Multiply" type="MathInput"/> <xs:element name="MultiplyResponse" type="MathOutput"/> <xs:element name="Divide" type="MathInput"/> <xs:element name="DivideResponse" type="MathOutput"/> </xs:schema> </types> ... </definitions>
Messages
The WSDL message element defines an abstract message that can serve as the input or output of an operation. Messages consist of one or more part elements, where each part is associated with either an element (when using document style) or a type (when using RPC style). The basic structure of a message definition is as follows (* means zero or more and ? means optional):<definitions .... > <message name="nmtoken"> * <part name="nmtoken" element="qname"? type="qname"?/> * </message> </definitions>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:y="http://example.org/math/" xmlns:ns="http://example.org/math/types/" targetNamespace="http://example.org/math/" > ... <message name="AddMessage"> <part name="parameter" element="ns:Add"/> </message> <message name="AddResponseMessage"> <part name="parameter" element="ns:AddResponse"/> </message> <message name="SubtractMessage"> <part name="parameter" element="ns:Subtract"/> </message> <message name="SubtractResponseMessage"> <part name="parameter" element="ns:SubtractResponse"/> </message> ... </definitions>
Note The message and type definitions in WSDL are considered to be abstract definitions. This means you don't know how they'll appear in the concrete message format until you've applied a binding to them. For example, if you use one abstract message with two different bindings, it's possible that the two concrete messages will look different. Only with 'literal' bindings are the abstract definitions guaranteed to accurately describe the concrete message format. See the Bindings section for more details.
Interfaces (portTypes)
The WSDL portType element defines a group of operations, also known as an interface in most environments. Unfortunately, the term "portType" is quite confusing so you're better off using the term "interface" in conversation. WSDL 1.2 has already removed "portType" and replaced it with "interface" in the current draft of the language.A portType element contains zero or more operation elements. The basic structure of a portType is as follows (* means zero or more):
<definitions .... > <portType name="nmtoken"> <operation name="nmtoken" .... /> * </portType> </definitions>
For example, an input element followed by an output element defines a request-response operation, while an output element followed by an input element defines a solicit-response operation. An operation that only contains an input element defines a one-way operation, while an operation that only contains an output element defines a notification operation. Table 2 describes the four MEP primitives defined by WSDL.
Table 2. Message Exchange Patterns
MEP | Description |
One-way | The endpoint receives a message. |
Request-response | The endpoint receives a message and sends a correlated message. |
Solicit-response | The endpoint sends a message and receives a correlated message. |
Notification | The endpoint sends a message. |
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:y="http://example.org/math/" xmlns:ns="http://example.org/math/types/" targetNamespace="http://example.org/math/" > ... <portType name="MathInterface"> <operation name="Add"> <input message="y:AddMessage"/> <output message="y:AddResponseMessage"/> </operation> <operation name="Subtract"> <input message="y:SubtractMessage"/> <output message="y:SubtractResponseMessage"/> </operation> <operation name="Multiply"> <input message="y:MultiplyMessage"/> <output message="y:MultiplyResponseMessage"/> </operation> <operation name="Divide"> <input message="y:DivideMessage"/> <output message="y:DivideResponseMessage"/> </operation> </portType> ... </definitions>
No comments:
Post a Comment