Tuesday, February 15, 2011

Web services stack de-mystified – Case study

    In my previous article I touched upon the topic of WS-Stack. Here I try to go into details of the stack, trying to de-mystify the complexity that is associated with any web service implementation of the stack. For the case of discussion let us consider a Case Study –

Project: A Stock Ticker Service. – This service is provided by a Stock broker to all his clients who can check the price of any stock in real time using web services.

Requirements: Input of the Stock Ticker Service will be a 4 digit stock code. Output will be the price in Rs.

Stack: HTTP/SOAP/WSDL

    With this basic information under the belt let us start to build the representation of such a service. The actual "service" implementation would be a complex method that derives the price based on lots of parameters but for simplicity let us keep the method simple.

public float getStockTicker(String stockCode){
  if(stockCode.equals("STC1"){
    return 100.50;
  }
  else
    return 0.00;
}


The above method as discussed in the requirements takes an input of a string stock code and returns the price of the stock. Now if we were to create a sample message for the same using SOAP the message would look like.

<env:Envelope xmlns: env="http://www.w3.org/2003/05/soap-envelope" >
  <env:Header></env:Header>
  <env:Body>
    <st:getStockTicker xmlns:st="http://stockticker.example/sample" >
      <st:stockCode>STC1</st:stockCode>
    </st:getStockTicker>
  </env:Body>
</env:Envelope>


And the response to the above would look like the below:

<env:Envelope xmlns: env="http://www.w3.org/2003/05/soap-envelope" >
  <env:Header></env:Header>
  <env:Body>
    <st:getStockTickerResponse xmlns:st="http://stockticker.example/sample" >
        <st:price>100.50</st:price>
    </st:getStockTickerResponse>
  </env:Body>
</env:Envelope>


Without going too much into the details of the SOAP let us briefly look at the highlights of SOAP.

SOAP is an XML protocol which contains an Envelope in a namespace defined by "http://www.w3.org/2003/05/soap-envelope" (henceforth denoted as SOAP: ). The Envelope contains 2 child elements The SOAP:Header and SOAP:Body. The header element contains information dealing with extensibility data while the Body contains information pertaining to the request/response. More details about SOAP would be discussed in the further articles. In the meantime you can read more about SOAP here. The main advantage of SOAP is that it allows us to define a standard structure for the XML message that is being passed. For example when we see the above message we know that the contents of the SOAP:Body tag are of use to the function that we have written.

Now once we know the details of the request and response we need to send it to all the clients who want to use it. For such a small request/response sending a sample request/response and some documentation is enough but if the sample request is much more complicated then we need a standard way to describe the request/response and also the location of the service. This standard way is provided by WSDL. Have a look at the sample WSDL created for the above example.

<wsdl:definitions name="StockQuote" targetNamspace="http://stockticker.example/sample/wsdl" 
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl" xmlns:sample="http://stockticker.example/sample" 
  xmlns:tns="http://stockticker.example/sample/wsdl">
  <wsdl:types> <!-- defines the xml schema for the required input and response -->
    <xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema" 
        targetNamespace="http://stockticker.example/sample">
      <xsd:complexType name="getStockTicker"> <!-- request schema definition -->
        <xsd:all>
          <xsd:element name="stockCode" type="xsd:string" />
        </xsd:all>
      </xsd:complexType>

      <xsd:complexType name="getStockTickerResponse"> <!-- response schema definition -->
        <xsd:all>
          <xsd:element name="price" type="xsd:float" />
        </xsd:all>
      </xsd:complexType>
    </xsd:schema>
  </wsdl:types>

  <!-- message defines the request and response for an operation. -->
  <wsdl:message name="getStockTicker"  >
    <wsdl:part name="request" element="sample:getStockTicker" />
  </wsdl:message>

  <wsdl:message name="getStockTickerResponse"  >
    <wsdl:part name="response" element="sample:getStockTickerResponse" />
  </wsdl:message>

  <!-- port Type is a collection of operations. This is like an interface definition. 
           The operations that are exposed in a web service are given out here-->
  <wsdl:portType name="StockTickerPortType" >
    <wsdl:operation name="getStockTicker">
      <wsdl:input message="tns:getStockTicker"/>
      <wsdl:output  message="tns:getStockTickerResponse"/>
    </wsdl:operation>
  </wsdl:portType>


  <!-- The above information tells us what are the different services 
         that are exposed and what are the request response params -->
  <!-- The next part describes HOW to access the request / response and where to access them -->


  <wsdl:binding name="StockTickerBinding" type="tns:StockTickerPortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getStockTicker">
      <soap:operationsoapAction="" />
      <wsdl:input message="tns:getStockTicker">
        <soap:body use="literal" parts="request" />
      </wsdl:input>
      <wsdl:output  message="tns:getStockTickerResponse">
      <soap:body use="literal" parts="response" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <!-- In the above mapping we describe that we want the operation getStockTicker to use SOAP binding. 
       The request and response content format i.e. the contents of the SOAP body are also defined.-->


  <wsdl:service name="StockTickerService">
    <wsdl:port name="StockTickerPort" binding="tns:StockTickerBinding">
      <soap:address location="http://stockticker.example/service/getStockTicker" />
    </wsdl:port>
  </wsdl:service>

  <!-- The wsdl service is used to provide the actual endpoint 
      of the service at which it would be available -->
</wsdl:definitions>

The comments for the WSDL are provided inline. The basic job of the WSDL is divided into two parts. In the first part the WSDL defined the input and output parameters and also describes the operations that are exposed. In the second part the WSDL describes how the operation can be invoked (what scheme of XML messaging and which network protocol to use) and also the location at which it is available. Now if we are able to provide this sample WSDL to any client. They can understand from the WSDL how to create a sample request and call the service. To do the same the client needs to parse the WSDL, create the SOAP message from Objects , Connect to the server , wait for response , convert response into objects. This entire process is done by any implementation API (ex. Axis, JAX-WS or Spring-WS etc..). The UDDI and BPL are advanced concepts that would be discussed in details later.





No comments:

Post a Comment