Standard ruby installation comes with soap4r but it's better to use the latest version, so install the gem.
sudo gem install soap4r
Then you should know the url of the wsdl of the service you want to consume, we are going to use this which is freely available:
http://www.webservicex.net/CurrencyConvertor.asmx?WSDL
once you have the url, there are 2 options:
1. create proxy classes with a utility called wsdl2ruby which resides on the bin directory of your library installation.
2. create the driver and call the methods directly passing a hash in the form of an XML as parameter.
The first one didn't work for me because the classes were not representing exactly the wsdl. There are possibly some wsdl directives which the utility doesn't recognizes, that depends on the service. So my only choice was the second one which ended to be more intuitive.
Hashes and XML
It's very easy to transform xml into hashes and viceversa, in Rails if you have a hash instance you can simply call my_hash.to_xml and it returns the xml string with the keys as nodes and the data associated inside.
these are a couple of examples
For example, suppose you have this hash:
{
"band" => {
"guitars" => [{"name" => "Allan Holdsworth"},{"name" => "Frank Gambale"}],
"drums" => "Vinnie Colaiuta",
"bass" => "Gary Willis"
}
}
it will turn into this XML:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<hash>
<band>
<bass>Gary Willis</bass>
<drums>Vinnie Colaiuta</drums>
<guitars type=\\\"array\\\">
<guitar>
<name>Allan Holdsworth</name>
</guitar>
<guitar>
<name>Frank Gambale</name>
</guitar>
</guitars>
</band>
</hash>
The idea is very simple, xml tags can be nested defining hashes of hashes, and a tag which expects several same tags on the inside has to be defined with an array.
You can go the other way with Hash.from_xml and passing the xml
So Hash.from_xml(band.to_xml) should return the original hash.
Now lets checkout the web service definition
you can ckeckout the web service methods in:
http://www.webservicex.net/CurrencyConvertor.asmx
the web service definition is in:
http://www.webservicex.net/CurrencyConvertor.asmx?WSDL
you can go to the only method available in this service on:
http://www.webservicex.net/CurrencyConvertor.asmx?op=ConversionRate
go to the section which describes the soap protocol and there is the exchanging xml messages format look in the soap protocol part, this is where it describes the method parameters:
...
<ConversionRate xmlns=\"http://www.webserviceX.NET/\">
<FromCurrency>AFA or ALL or DZD ....</FromCurrency>
<ToCurrency>AFA or ALL or DZD ...</ToCurrency>
</ConversionRate>
...
So the parameters will be the hash:
{"FromCurrency" => "...", "ToCurrency" => "..."}
and the response will be in:
...
<ConversionRateResponse xmlns=\"http://www.webserviceX.NET/\">
<ConversionRateResult>double</ConversionRateResult>
</ConversionRateResponse>
...
in this case the response will be only a "double"
Now the code:
In rails add this to your environment.rb to include the latest library version:
config.gem 'soap4r', :lib => 'soap/wsdlDriver', :version => '1.5.8'
you should change the version number to the latest you have install
If you are using just Ruby:
require "rubygems"
gem 'soap4r'
require "soap/wsdlDriver"
and this is the Ruby code:
require "rubygems"
gem "soap4r"
require "soap/wsdlDriver"
wsdl = "http://www.webservicex.net/CurrencyConvertor.asmx?WSDL"
driver = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
#driver.wiredump_dev = STDOUT
params = {
"FromCurrency" => "USD",
"ToCurrency" => "UYU"
}
puts driver.conversionRate(params).conversionRateResult
with driver.wiredump_dev = STDOUT all the exchanging messages are going to STDOUT. Uncomment this if you want to know the exchanging xml messages.
The response is everything inside the "<conversionrateresult>" tag, in this case is a simple value which can be parsed easily. Normally it's an xml that can be parsed with any Ruby xml library.
So, the steps are:
-create the driver from the wsdl
-build a hash based on the web service method parameters, which can be taken from the asmx method description
-call the driver method with the hash as parameter, and call the xxxResult method, to get the string response
hope it helps somebody
3 comments:
This helped a lot. Thanks!
Glad it helped you
Exactly what I've been looking for over the last 2 days! Thanks for helping out a Ruby noob who is used to clicking "Add Web Reference" in Visual Studio.
Post a Comment