Using a WSDL File to Make SOAP Calls Easier






Using a WSDL File to Make SOAP Calls Easier

Credit: Kevin Marshall

Problem

You need to create a client for a SOAP-based web service, but you don't want to type out the definitions for all the SOAP methods you'll be calling.

Solution

Most web services provide a WSDL file: a machine-readable description of the methods they offer. Ruby's SOAP WSDL Driver can parse a WSDL file and make the appropriate methods available automatically.

This code uses the xmethods.com SOAP web service to get a stock price. In Recipe 16.7, we defined the getQuote method manually. Here, its name and signature are loaded from a hosted WSDL file. You still have to know that the method is called getQuote and that it takes one string, but you don't have to write any code telling Ruby this.

	require 'soap/wsdlDriver'
	wsdl = 'http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl'
	driver = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver

	puts "Stock price: %.2f" % driver.getQuote('TR')
	# Stock price: 28.78

Discussion

According to the World Wide Web Consortium (W3), "WSDL service definitions provide documentation for distributed systems and serve as a recipe for automating the details involved in applications communication."

What this means to you is that you don't have to tell Ruby which methods a web service provides, and what arguments it expects. If you feed a WSDL file in to the Driver Factory, Ruby will give you a Driver object with all the methods already defined.

There are only a few things you need to know to build useful SOAP clients with a WSDL file. I'll illustrate with some code that performs a Google search and prints out the results.

  1. Start with the URL to the WSDL file:

    	require 'soap/wsdlDriver'
    	wsdl = 'http://api.google.com/GoogleSearch.wsdl'
    	driver = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
    

  2. Next you need the name of the SOAP method you want to call, and the expected types of its parameters:

    	my_google_key = 'get yours from https://www.google.com/accounts'
    	my_query = 'WSDL Ruby'
    	XSD::Charset.encoding = 'UTF8'
    	result = driver.doGoogleSearch(my_google_key, my_query, 0, 10, false,
    	                               '', false, '', '', '')
    

    Without WSDL, you need to tell Ruby that methods a web service exposes, and what parameters it takes. With WSDL, Ruby loads this information from the WSDL file. Of course, you still need to know this information so you can write the method call. In this case, you'll also need to sign up for an API key that lets you use the web service.

    The Google search service returns data encoded as UTF-8, which may contain special characters that cause mapping problems to Ruby strings. That's what the call to XSD::Charset.encoding = 'UTF8' is for. The Soap4r and WSDL Factory libraries rely on the XSD library to handle the data type conversions from web services to native Ruby types. By explicitly telling Ruby to use UTF-8 encoding, you'll ensure that any special characters are properly escaped within your results so you can treat them as proper Ruby Strings.

    	result.class
    	# => SOAP::Mapping::Object
    
    	(result.methods - SOAP::Mapping::Object.instance_methods).sort
    	# => ["directoryCategories", "directoryCategories=", "documentFiltering",
    	# …
    	# "searchTips", "searchTips=", "startIndex", "startIndex="]
    

  3. Here's how to treat the result object you get back:

    	"Query for: #{my_query}"
    	# => "Query for: WSDL Ruby"
    	"Found: #{result['estimatedTotalResultsCount']}"
    	# => "Found: 159000"
    	"Query took about %.2f seconds" % result['searchTime']
    	# => "Query took about 0.05 seconds"
    
    	result["resultElements"].each do |rec|
    	  puts "Title: #{rec["title"]}"
    	  puts "URL: #{rec["URL"]}"
    	  puts "Snippet: #{rec["snippet"]}"
    	  puts
    	end
    	# Title: <b>wsdl</b>: <b>Ruby</b> Standard Library Documentation
    	# URL: http://www.ruby-doc.org/stdlib/libdoc/wsdl/rdoc/index.html
    	# Snippet: #<SOAP::Mapping::Object:0xb705f560>
    	#
    	# Title: how to make SOAP4R read <b>WSDL</b> files?
    	# URL: http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-talk/37623
    	# Snippet: Subject: how to make SOAP4R read <b>WSDL</b> files? <b>…</b>
    	# …
    

    We expect the Google search service to return a complex SOAP type. The XSD library will convert it into a Ruby hash, containing some keys like EstimatedTotalResultsCount and resultElementsthe latter points to an array of search results. Every search result is itself a complex type, and XSD maps it to a hash as well: a hash with keys like snippet and URL.

See Also

  • Recipe 16.4, "Writing a SOAP Client," provides a more generic example of a SOAP client

  • Recipe 16.6, "Searching the Web with Google's SOAP Service," shows what searching Google would be like without WSDL

  • https://www.google.com/accounts to get an access key to Google Web APIs



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows