Credit: Kevin Marshall
You need to create a client for a SOAP-based web service, but you don want to type out the definitions for all the SOAP methods youll be calling.
Most web services provide a WSDL file: a machine-readable description of the methods they offer. Rubys 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 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
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 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. Ill illustrate with some code that performs a Google search and prints out the results.
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
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, youll 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. Thats 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, youll 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="]
Heres 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: wsdl: Ruby Standard Library Documentation
# URL: http://www.ruby-doc.org/stdlib/libdoc/wsdl/rdoc/index.html
# Snippet: #
#
# Title: how to make SOAP4R read WSDL files?
# URL: http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-talk/37623
# Snippet: Subject: how to make SOAP4R read WSDL files? …
# …
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.
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration