How do I move from SOAP:RPC:Driver to Savon
Question
As discussed elsewhere the SOAP::RPC::Driver
which was available in Ruby 1.8 has been removed in Ruby 1.9. People suggested using the Savon gem, but I can't find any tutorials on how to convert existing code, specifically for endpoints for which there is no WSDL available.
For example, with SOAP::RPC::Driver
we could write:
require 'soap/rpc/driver'
client = SOAP::RPC::Driver.new 'http://example.com/endpoint', 'MY_NAMESPACE'
Add methods (since in my case I have no WSDL available):
client.add_method 'MyMethod', 'Arg1', 'Arg2'
And then call them:
response = client.MyMethod arg_one arg_two
I don't see how to add methods like this with Savon.
Solution
When not using a WSDL one must set up wsdl
explicitly (I find this a little counter-intuitive, but it works):
require 'savon'
client = Savon::Client.new do
wsdl.endpoint = 'http://example.com/endpoint'
wsdl.namespace = 'MY_NAMESPACE';
end
I don't believe there is an equivalent to add_method
in Savon, but you should then be able to make a request thus:
response = client.request 'MyMethod' do
soap.body = { 'Arg1' => arg_one' }
end
However when I did this I received the following error:
Savon::SOAP::Fault: (SOAP-ENV:Client) SOAPAction shall match 'uri#method' if present
I was able to work around this by explicitly setting SOAPAction
:
response = client.request 'MyMethod', soap_action: '#MyMethod' do ...
Finally I got this error:
Savon::SOAP::Fault: (SOAP-ENV:Client) Denied access to method (MyMethod) in class (main) at /usr/lib/perl5/site_perl/5.8.8/SOAP/Lite.pm line 2128.
This seems to be because the given wsdl.namespace
isn't passed as expected with the request. I was able to resolve this by explicitly setting it in both soap_action
and xmlns
:
response = client.request 'MyMethod', soap_action: 'MY_NAMESPACE#MyMethod', xmlns: 'MY_NAMESPACE'