Evaluate Weigh the pros and cons of technologies, products and projects you are considering.

Ruby as a Web service client language

In this tip, William Brogden discusses one of the most popular "scripting" languages, Ruby.

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 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:element minOccurs="0" maxOccurs="1" name="symbol" type="s:string" />

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:any />

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.


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. https://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/

Dig Deeper on Topics Archive

Start the conversation

Send me notifications when other members comment.

Please create a username to comment.