AddThis Social Bookmark Button

Print

.NET Framework Essentials, 2nd Ed.: Web Services, Part 1
Pages: 1, 2, 3

Web Services Wire Formats

You may have heard the phrase "DCOM is COM over the wire." Web Services are similar to DCOM except that the wire is no longer a proprietary communication protocol. With Web Services, the wire formats rely on more open Internet protocols such as HTTP or SMTP.



A Web Service is more or less a component running on the web server, exposed to the world through standard Internet protocols. Microsoft .NET Web Services currently supports three protocols: HTTP GET, HTTP POST, and SOAP (Simple Object Access Protocol), explained in the next sections. Because these protocols are standard protocols for the Web, it is very easy for the client applications to use the services provided by the server.

HTTP GET and HTTP POST

As their names imply, both HTTP GET and HTTP POST use HTTP as their underlying protocol. The GET and POST methods of the HTTP protocol have been widely used in ASP (Active Server Pages), CGI, and other server-side architectures for many years now. Both of these methods encode request parameters as name/value pairs in the HTTP request. The GET method creates a query string and appends it to the script's URL on the server that handles the request. For the POST method, the name/value pairs are passed in the body of the HTTP request message.

SOAP

Similar to HTTP GET and HTTP POST, SOAP serves as a mechanism for passing messages between the clients and servers. In this context, the clients are Web Services consumers, and the servers are the Web Services. The clients simply send an XML-formatted request message to the server to get the service. The server responds by sending back yet another XML-formatted message. The SOAP specification describes the format of these XML requests and responses. It is simple, yet it is extensible, because it is based on XML.

SOAP is different than HTTP GET and HTTP POST because it uses XML to format its payload. The messages being sent back and forth have a better structure and can convey more complex information compared to simple name/value pairs in HTTP GET/POST protocols. Another difference is that SOAP can be used on top of other transport protocols, such as SMTP in addition to HTTP.

Web Services Description (WSDL)

For Web Service clients to understand how to interact with a Web Service, there must be a description of the method calls, or the interface that the Web Service supports. This Web Service description document is found in an XML schema called WSDL (Web Services Description Language). Remember that type libraries and IDL scripts are used to describe a COM component. Both IDL and WSDL files describe an interface's method calls and the list of in and out parameters for the particular call. The only major difference between the two description languages is that all descriptions in the WSDL file are done in XML.

In theory, any WSDL-capable SOAP client can use the WSDL file to get a description of your Web Service. It can then use the information contained in that file to understand the interface and invoke your Web Service's methods.

WSDL Structure

The root of any Web Service description file is the <definitions> element. Within this element, the following elements provide both the abstract and concrete description of the service:

Types
A container for datatype definitions.

Message
An abstract, typed definition of the data being exchanged between the Web Service providers and consumers. Each web method has two messages: input and output. The input describes the parameters for the web method; the output describes the return data from the web method. Each message contains zero or more <part> parameters. Each parameter associates with a concrete type defined in the <types> container element.

Port type
An abstract set of operations supported by one or more endpoints.

Operation
An abstract description of an action supported by the service. Each operation specifies the input and output messages defined as <message> elements.

Binding
A concrete protocol and data-format specification for a particular port type. Similar to port type, the binding contains operations, as well as the input and output for each operation. The main difference is that with binding, we are now talking about actual transport type and how the input and output are formatted.

Service
A collection of network endpoints--ports. Each of the Web Service wire formats defined earlier constitutes a port of the service (HTTP GET, HTTP POST, and SOAP ports).

Port
A single endpoint defined by associating a binding and a network address. In other words, it describes the protocol and data-format specification to be used as well as the network address of where the Web Service clients can bind to for the service.

The following shows a typical WSDL file structure:


<definitions name="" targetNamespace="" xmlns:...>

  <types>...</types>

  <message name="">...</message>
  ...

  <portType name="">
    <operation name="">
      <input message="" />
      <output message="" />
    </operation>
    ...
  </portType>
  ...

  <binding name="">
    <protocol:binding ...>
    <operation name="">
      <protocol:operation ...>
      <input>...</input>
      <output>...</output>
    </operation>
    ...
  </binding>
  ...

  <service name="">
    <port name="" binding="">
      <protocol:address location="" />
    </port>
    ...
  </service>
</definitions>

The <types> element contains physical type descriptions defined in XML Schema (XSD). These types are being referred to from the <message> elements.

For each of the web methods in the Web Service, there are two messages defined for a particular port: input and output. This means if a Web Service supports all three protocols: SOAP, HTTP GET, and HTTP POST, there will be six <message> elements defined, one pair for each port. The naming convention used by the Microsoft .NET autogenerated WSDL is:

MethodName + Protocol + {In, Out}

For example, a web method called GetBooks( ) has the following messages:


<message name="GetBooksSoapIn">...</message>
<message name="GetBooksSoapOut">...</message>
<message name="GetBooksHttpGetIn">...</message>
<message name="GetBooksHttpGetOut">...</message>
<message name="GetBooksHttpPostIn">...</message>
<message name="GetBooksHttpPostOut">...</message>

For each protocol that the Web Service supports, there is one <portType> element defined. Within each <portType> element, all operations are specified as <operation> elements. The naming convention for the port type is:

WebServiceName + Protocol

To continue our example, here are the port types associated with the Web Service that we build later in this chapter, PubsWS:


<portType name="PubsWSSoap">
  <operation name="GetBooks">
    <input message="GetBooksSoapIn" />
    <output message="GetBooksSoapOut" />
  </operation>
</portType>

<portType name="PubsWSHttpGet">
  <operation name="GetBooks">
    <input message="GetBooksHttpGetIn" />
    <output message="GetBooksHttpGetOut" />
  </operation>
</portType>
 
<portType name="PubsWSHttpPost">
  <operation name="GetBooks">
    <input message="GetBooksHttpPostIn" />
    <output message="GetBooksHttpPostOut" />
  </operation>
</portType>

We have removed namespaces from the example to make it easier to read.

While the port types are abstract operations for each port, the bindings provide concrete information on what protocol is being used, how the data is being transported, and where the service is located. Again, there is a <binding> element for each protocol supported by the Web Service:

<binding name="PubsWSSoap" type="s0:PubsWSSoap">
  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 
                style="document" />
  <operation name="GetBooks">
    <soap:operation soapAction="http://tempuri.org/GetBooks"
                    style="document" />
    <input>
      <soap:body use="literal" />
    </input>
    <output>
      <soap:body use="literal" />
    </output>
  </operation>
</binding>
 
<binding name="PubsWSHttpGet" type="s0:PubsWSHttpGet">
  <http:binding verb="GET" />
  <operation name="GetBooks">
    <http:operation location="/GetBooks" />
    <input>
      <http:urlEncoded />
    </input>
    <output>
      <mime:mimeXml part="Body" />
    </output>
  </operation>
</binding>
 
<binding name="PubsWSHttpPost" type="s0:PubsWSHttpPost">
  <http:binding verb="POST" />
  <operation name="GetBooks">
    <http:operation location="/GetBooks" />
    <input>
      <mime:content type="application/x-www-form-urlencoded" />
    </input>
    <output>
      <mime:mimeXml part="Body" />
    </output>
  </operation>
</binding>

For SOAP protocol, the binding is <soap:binding>, and the transport is SOAP messages on top of HTTP protocol. The <soap:operation> element defines the HTTP header soapAction, which points to the web method. Both input and output of the SOAP call are SOAP messages.

For the HTTP GET and HTTP POST protocols, the binding is <http:binding> with the verb being GET and POST, respectively. Because the GET and POST verbs are part of the HTTP protocol, there is no need for the extended HTTP header (like soapAction for SOAP protocol). The only thing we need is the URL that points to the web method; in this case, the <soap:operation> element contains the attribute location, which is set to /GetBooks.

The only real difference between the HTTP GET and POST protocols is the way the parameters are passed to the web server. HTTP GET sends the parameters in the query string, while HTTP POST sends the parameters in the form data. This difference is reflected in the <input> elements of the operation GetBooks for the two HTTP protocols. For the HTTP GET protocol, the input is specified as <http:urlEncoded />, whereas for the HTTP POST protocol, the input is <mime:content type="application/x-www-form-urlencoded" />.

Looking back at the template of the WSDL document, we see that the only thing left to discuss is the <service> element, which defines the ports supported by this Web Service. For each of the supported protocol, there is one <port> element:


<service name="PubsWS">
 
  <port name="PubsWSSoap" binding="s0:PubsWSSoap">
    <soap:address
      location="http://.../PubsWs.asmx" />
  </port>
 
  <port name="PubsWSHttpGet" binding="s0:PubsWSHttpGet">
    <http:address 
      location="http://.../PubsWs.asmx" />
  </port>
 
  <port name="PubsWSHttpPost" binding="s0:PubsWSHttpPost">
    <http:address 
      location="http://.../PubsWs.asmx" />
  </port>
 
</service>

Even though the three different ports look similar, their binding attributes associate the address of the service with a binding element defined earlier. Web Service clients now have enough information on where to access the service, through which port to access the Web Service method, and how the communication messages are defined.

Although it is possible to read the WSDL and manually construct the HTTP[1] conversation with the server to get to a particular Web Service, there are tools that autogenerate client-side proxy source code to do the same thing. We show such a tool in "Web Services Consumers" later in this chapter.

Pages: 1, 2, 3

Next Pagearrow