Tip

Ruby as a Web service client language

A number of interesting languages described as "scripting languages" have great potential for building Web service client applications. The term "scripting language" seems to commonly be applied to languages created as tools for "quick and dirty" solution building from existing components rather than as complete system programming languages. These languages typically accomplish a lot in a few statements and have automatic management of details such as memory allocation.

Based on the TIOBE language popularity survey, the most popular "scripting" languages are currently PHP, Perl, Python, JavaScript and Ruby. Perl was the real workhorse of the early Internet, but is decreasing in popularity. PHP as a tool for creating Web pages continues to increase in popularity, but I decided to take a look at

    Requires Free Membership to View

Ruby. I have been impressed with all the industry buzz about the database oriented open source "Rails" Web framework which is written in Ruby.

The Ruby programming language has been around since 1995 so it is about the same age as Java. However, as the vision of a single creator, Yukihiro Matsumoto, rather than the creation of a corporate development team, it has developed more slowly and without so much publicity. In the last few years a surge of interest in the open source community has promoted a lot of Ruby development. The language is currently at version 1.8.4 with a major revision to 1.9 coming.

Ruby is an interpreted object-oriented language with dynamic typing. A typical working environment for Ruby includes an interactive interface for rapid testing. The current standard library includes extensive classes for dealing with XML documents as well as specific classes for accessing Web services in XML-RPC and SOAP styles.

A Ruby Example of XML-RPC

Here is all of the Ruby code required to access a Web service in the XML-RPC style, with line numbers added for discussion.

1. require 'xmlrpc/client'

2. server = XMLRPC::Client.new2("http://time.xmlrpc.com/RPC2")

3. result = server.call("currentTime.getCurrentTime")

4. printf("xmlrpc time %i:%i:%i ", result.hour, result.min, result.sec)

Line 1 causes the "xmlrpc/client" code to be loaded from the standard library path. Line 2 creates an instance of the Client class using a url and standard defaults. In line 3, as you may recall from an earlier article, the XML-RPC protocol uses a simple set of data types and does not require namespaces. One of the data types is a timestamp, which in Ruby XML-RPC becomes an instance of the DateTime class returned in line 3 from the service call. Line 4 uses the familiar "printf" syntax to print the values of the individual members of the DateTime object.

A Ruby SOAP Example

A number of versions of SOAP tools for Ruby have been created by the dynamic open source Ruby community. Encouraged by my success with XML-RPC, I decided to try the standard library tool that can work directly from a WSDL. It turned out to be a lot trickier than I expected because the documentation and examples are not as well developed as, for example, Sun's Web Services Developer's Pack for Java. Here is the full program required to get a stock quote, with line numbers added for discussion.

1. require 'soap/wsdlDriver'

2. wsdl_url = "http://ws.invesbot.com/stockquotes.asmx?WSDL"

3. soap = SOAP::WSDLDriverFactory.new( wsdl_url ).create_rpc_driver

4. soap.wiredump_file_base = "soapresult"

5. param = {"symbol" => "WAG" }

6. result = soap.getQuote( param )

7. puts result.getQuoteResult.stockQuote.prevClose

Line 1 loads the "soap/wsdlDriver" code from the standard library. Line 2 creates a variable containing a URL for accessing the WSDL file describing a stock quote service. Note that in Ruby, the variable named "wsdl_url" does not have an associated class type, it could refer to any object type.

Line 3 performs a lot of behind-the-scenes work that ends up creating an instance of a class customized for the Web service described by the WSDL. The resulting object has been created with methods whose names are derived from the entries in the WSDL plus variables such as "wiredump_file_base" which gets set in line 4. If this variable is set, the full text of the SOAP request and response will be written to local files, a big help in dealing with a complex Web service.

Line 5 creates a "hash" -- an array which associates the name "symbol" with a stock symbol -- in this case the "WAG" code for Walgreens. This hash is going to map the stock code to the SOAP request element. Here is the portion of the WSDL that describes the GetQuote method call:

  <s:element name="GetQuote">
     <s:complexType>
       <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="symbol" type="s:string" />
       </s:sequence>
     </s:complexType>
  </s:element>

Line 6 calls the getQuote method, a method in the custom class which was created dynamically by Ruby from the WSDL. This method does all the work of formatting the SOAP request, contacting the Web service and parsing the SOAP response. The "result" it returns is a generic "Mapping" object containing the data of the SOAP response. Figuring out the exact syntax to get usable data out of this response took a bit of fiddling. Perusal of the full text of the SOAP response revealed that this service returns quite a lot of data which is described in the WSDL as simply:

  <s:element minOccurs="0" maxOccurs="1" name="GetQuoteResult">
    <s:complexType mixed="true">
       <s:sequence>
         <s:any />
       </s:sequence>
     </s:complexType>
  </s:element>

The actual content we are after is in a "PrevClose" element contained in the "StockQuote" element contained in the "GetQuoteResult" element. Line 7 outputs this content by addressing it as "getQuoteResult.stockQuote.prevClose" rather than using the element names using initial upper case letters such as "StockQuote." I'm not sure why the Ruby library does this, but discovering this trick took a lot of fiddling around.

As you can see from the samples, the core of a Web service client in Ruby can be created in a very few lines using the standard library. Compared to a language with a longer history and corporate backing, you can expect to do a bit more experimentation, so the rapid testing possible with a scripting language will be a big help.

References

The Wikipedia entry for "Scripting Languages" has a nice summary of the usage of the term and has links to useful entries on a number of languages. http://en.wikipedia.org/wiki/Scripting

The TIOBE Programming Community Index Web site (updated monthly.) http://www.tiobe.com/tpci.htm

The REXML library of XML parsers as used in the Ruby standard release. http://www.germane-software.com/software/rexml/


This was first published in April 2006

There are Comments. Add yours.

 
TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.