Use Dojo to process web service responses

Simplify the use of web services with Dojo

Using web services exposes functionality in a language- and platform-independent manner. On the client side, Dojo is becoming increasingly popular as a JavaScript tool for providing a rich client experience with minimal programming effort. Learn to leverage your existing use of Dojo to parse and process web service responses.

Share:

Brian M. Carey, Senior Systems Engineer, Triangle Information Solutions

Brian Carey is an information systems consultant specializing in Java, Java Enterprise, PHP, Ajax, and related technologies. You can follow Brian Carey on Twitter at http://twitter.com/brianmcarey.



27 July 2010

Also available in Chinese Russian Japanese

What is a web service?

A web service is a web-based application programming interface (API) that is accessed via Hypertext Transfer Protocol (HTTP). On the host side, certain operations are defined with an Extensible Markup Language (XML) known as the Web Services Description Language (WSDL). The specification for exchanging information between the client and the host is known as Simple Object Access Protocol, or SOAP. (Web services is, indeed, a world of acronyms.)

From a real-world perspective, web services facilitate a centralized access point for information interchange. As the name implies, they provide a service to clients around the world. For example, web services can be used to get the latest headlines, the newest listings at an online book store, or historical fishing reports from a particular geographic region. Also implied by the name is that this information is frequently reported via a website, such as a professional journalistic initiative or a personal blog.

What is Dojo?

Dojo is an open source JavaScript user interface (UI) toolkit that facilitates rapid deployment of JavaScript applications. Think of it as a series of JavaScript libraries that make writing JavaScript code less time-consuming and complex.

One of the major components of the Dojo framework is called Dojo Base. This portion of the Dojo library deals with the intricacies of event handling, Asynchronous JavaScript + XML (Ajax) calls, Cascading Style Sheets (CSS) queries, effects, and more.

Beyond Dojo Base is a widget called Dijit—one of Dojo's most popular features. It is a series of reusable client-side components that you can practically drag and drop into your own application. To customize the look and feel of your application, you will only need to make a few simple configuration changes for most of these widgets.

Assembling an application using Dojo with a web service

The board of directors at FishinHole.com has decided that displaying the company's catalog (and making it searchable) via a web service will promote its products more widely across the web and give it a competitive edge. The board has asked you to create the web service and produce a prototype that shows how it can be accessed with a fairly simple web page—by tomorrow.

Since the company is already using PHP for its online catalog, it is logical to use PHP for the web service as well. A PHP library called NuSOAP eases the rapid application development of web services using PHP, supports most of the SOAP 1.1 specification, and can also produce WSDL 1.1-compliant documents.

Now consider the client's needs: that the web service be "fairly simple." This calls for a web service that can run on a local personal computer without the aid of a PHP translator (or any other, for that matter). A simple Hypertext Markup Language (HTML) page with some JavaScript code can produce the desired result. Though your initial production is very simplistic, Dojo allows for expansion, which can include fancy user interface features later on. Since you're using Dojo anyway, you opt to use it for the XML processing as well in an effort to be consistent.

Deploying a simple web service

A web service like the one you're coding in PHP with NuSOAP returns a list of fishing lures that the company offers based on the lure type. In this fairly simple example, there are only three types: trolling, casting, and other.

Listing 1 shows how simple the production of a SOAP-compliant web service with PHP and NuSOAP is.

Listing 1. A simple web service in PHP
<?php
require_once('nusoap.php');
$server = new soap_server;
$server->register('retrieveByType');

function retrieveByType($type) {
    if ($type == 'trolling') {
        $arr[0] = 'Donzai Deep Swimmer 5 1/4 inch';
        $arr[1] = 'Yosubi Squid-like 4 inch';
        $arr[2] = 'Fortunata Imperial High Action';
    } else if ($type == 'casting') {
        $arr[0] = 'Silver Spring Mirrors Size 00';
        $arr[1] = 'Gold Spring Mirrors Size 0';
        $arr[2] = 'Mini Minnow Blue';
    } else {
        $arr[0] = 'None found!';
    }

    return $arr;
}

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

The first line (the require_once line) references the necessary NuSOAP library. To access it, you must first download it. See Resources for more information about the NuSOAP download.

Next, instantiate a PHP object named $server. This object is of the type soap_server, which is defined in the NuSOAP PHP library. When the client invokes one of the service operations, this object is used to handle the operation and return the results.

The next line registers a function as a web service operation. In this case, you have only one operation and, therefore, only one function. For the purposes of this example, the name of the operation and the name of the function are identical (though this is a good practice anyway because it eliminates confusion). When you invoke the SOAP operation called retrieveByType, the PHP function by the same name is called.

Next, code the aforementioned PHP function. Notice that this function accepts one parameter: type. This type is evaluated for one of two strings: trolling or casting. If either one of those strings matches the parameter, then the appropriate array of lures is returned. If no match is found, then the string None found! is returned.

The second to the last line reveals how the web service processes operation invocations. As you can see, the web service anticipates that the invocation will occur via a POST (as opposed to a GET) request. This is similar to the way form submissions are usually handled in web applications. This line also traps for a null value and converts it to an empty string to prevent problems during later processing.

Finally, the server object invokes its service function. This function accepts the POSTed data and returns the appropriate response to the client.

Your web service is complete. Name this file webservice.php and place it on your favorite host.

Invoking the service with JavaScript code

Because you're using Dojo to process and parse the XML that is returned from your new web service, you must reference the Dojo library at the beginning of your client code (as shown in Listing 2).

Listing 2. Referencing the Dojo library
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" 
	type="text/javascript"></script>

The above code goes in the head element of your HTML page. By referencing Dojo in this way, you won't need to download any libraries since it already exists elsewhere on the web. Unfortunately, if the referenced website goes down, so does your application. Fortunately, this occurrence is not likely with Google.

Listing 3 shows how the web service is invoked programmatically from the HTML page.

Listing 3. The invokeService() function
function invokeService(type) {
    soapMessage = '<?xml version="1.0" encoding="ISO-8859-1"?>';
    soapMessage+='<SOAP-ENV:Envelope SOAP-ENV:";
    soapMessage+=;encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"';
    soapMessage+=' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"';
    soapMessage+=' xmlns:xsd="http://www.w3.org/2001/XMLSchema"';
    soapMessage+=' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
    soapMessage+=' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"';
    soapMessage+=' xmlns:si="http://soapinterop.org/xsd">';
    soapMessage+=' <SOAP-ENV:Body> <ns1:retrieveByType ';
    soapMessage+='xmlns:ns1="http://fishinhole.com">';
    soapMessage+=' <type xsi:type="xsd:string">' + type + '</type>';
    soapMessage+=' </ns1:retrieveByType> </SOAP-ENV:Body> </SOAP-ENV:Envelope>';
   
    if(window.XMLHttpRequest) {
            httpRequest=new XMLHttpRequest();
	} else if (window.ActiveXObject) { 
            httpRequest=new ActiveXObject("Microsoft.XMLHTTP"); 
    }
                  
    httpRequest.open("POST",url,true);
    if (httpRequest.overrideMimeType) { 
            httpRequest.overrideMimeType("text/xml"); 
    }
    httpRequest.onreadystatechange=populateDiv;
      
    httpRequest.setRequestHeader("Man", url + " HTTP/1.1")
    httpRequest.setRequestHeader("MessageType", "CALL");
    httpRequest.setRequestHeader("Content-Type", "text/xml");

    httpRequest.send(soapMessage);
    valTimeout=setTimeout("timeout(httpRequest);",120000);              
}

Although it might appear to be a lot of coding, the contents of this listing is fairly straightforward for developers that are familiar with Ajax.

First, a SOAP-compliant message is constructed as a string. Most of the message is hardcoded. The exception is the lure type, which is one of three strings: trolling, casting, or other. These types will seem familiar, with the possible exception of other (which is put in place to test the None found! result).

After you create the SOAP message, ensure cross-browser compliance by adding a few additional lines of code. The appropriate HTTP request object is instantiated based on the type of browser that the client is using. This object is called httpRequest.

A POST method is used to access the web service; this is evident when the open function is executed against httpRequest. Your earlier coding created the expectation for this result. Where you choose to deploy the web service to will determine the url input parameter (which has a format similar to http://www.myhost.com/webservice.php).

The invocation of the onreadystatechange function on the httpRequest object is of particular importance to the functionality of this page. It is set to populateDiv, which is the name of the JavaScript function that acts as a callback when the web service responds.

The next few lines of code set specific header information. After that, the web service is officially called when the send method is invoked. Notice that the parameter input for that function is the SOAP message that was created earlier.

Listing 4 shows the JavaScript populateDiv function.

Listing 4. The populateDiv function
function populateDiv(){
   	try {
       if(httpRequest.readyState==4) {
            if(httpRequest.status==200) {
            clearTimeout(valTimeout);
          var text = httpRequest.responseText;
          var dom = dojox.xml.parser.parse(text); 
          var docNode = dom.documentElement; 
          var html = "";

          var returnElement = docNode.childNodes[0].childNodes[0].childNodes[0];

          for (var i = 0; i < returnElement.childNodes.length; i++) { 
           html +="<br/>" + 
        	dojox.xml.parser.textContent(returnElement.childNodes[i]);
          }

          var resultDiv=document.getElementById("resultDiv");
          resultDiv.innerHTML = html;
         	}
        } 
   	 } catch(e) { 
       alert("Error!"+e.description); 
     }      
}

Notice that because you are dealing with both a request/response mechanism and XML parsing, a try/catch block frames this entire function. You probably want to trap any exceptions that are encountered and output them for debugging purposes.

At this time, several checks are run. If a response is received, the request object registers a ready state of 4. If the response is valid, it registers a status of 200.

Once a valid response is received, the timeout variable is cleared, which means that you don't need to worry if your web service times out.

Next, the actual text of the response—which is in XML format and is probably strikingly similar to the response you coded earlier—is obtained. It will have an element that contains the text response based on the selected lure type.

Finally, Dojo is invoked to parse the returned XML SOAP message and to get a handle on the root element of the document in the next line of code.

You are looking for one or more item elements as returned by the NuSOAP web service. These elements are buried four deep in the response (hence the line that sets the returnElement object). In a way, you're looking for the great-great-grandchildren of the root element. To get those elements, iterate through each of the children of the great-grandchild (that element is called return, which explains the name of the JavaScript object).

Iterate through each of those great-great-grandchildren, extract only the text portion of the element (which is the lure description in this case), and prepend that text portion with a <br/> tag to separate each lure name with a line break.

Finally, obtain the DIV element, which is used to display the response. The HTML that is constructed is then placed in that DIV so it displays instantaneously.

Testing

Once you've put the client code and web service code in place, test your prototype.

The client can simply run on your local computer. Any web browser (such as Microsoft® Windows® Internet Explorer or Mozilla Firefox) can process a local HTML file, even if it uses JavaScript code.

When the web page appears, it shows a simple drop-down menu that allows you to select a lure type. If you select Trolling, the results will appear below the drop-down menu within moments. Select Casting and they will change. If you select Other, you will see None found!.

Conclusion

The board is impressed with your work; you met the deadline and created a "fairly simple" web service.

More importantly, you demonstrated a successful recipe using several easy-to-use technologies: PHP, NuSOAP, and Dojo. In doing so, you displayed your own competence and showed how application integration can be implemented quickly and efficiently. Finally, you managed to hide the complexities of web service implementation with this solution.

Maybe a promotion is in order.


Downloads

DescriptionNameSize
The PHP web service file used in this articlewebservice.php1KB
The client HTML/JavaScript codeclient.html2KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Web development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Open source
ArticleID=502395
ArticleTitle=Use Dojo to process web service responses
publish-date=07272010