Consuming SOAP services in Ruby
I know, I know, REST is cool and SOAP sucks. Rails is awesome and .NET blows. But the reality is I have to do a little bit of both.
Things at work are moving more and more toward Rails, but there’s still a large investment in a few .NET systems that must be maintained (until the decision is made to rewrite them in Rails). With that means there are a few SOAP services that I still need to work with. It turns out, this isn’t so bad.
Originally I thought I’d bring back AWS and deal with it that way. But from my experience, AWS has more support for generating services rather than consuming services. While AWS isn’t a terrible approach, there’s an easier way this can be handled: SOAP::WSDLDriverFactory. This is a straight-up Ruby solution that comes shipped with the standard library. It’s straight-forward to use and requires no XML parsing (which sort of surprised me).
As an example, one of the Rails applications I’m currently working on needed to have the ability perform certain actions under that users’ .NET account. Mainly, since the applications are completely separate (read: separate DB, separate users table), I needed to get the user id from the .NET system via their credentials in the Rails system. While this isn’t the actual implementation, you can see how easy this is to do.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | require 'soap/wsdlDriver' class SomeDotNetWrapper attr_accesssor :endpoint, :service def initialize(endpoint=nil, service=nil) @endpoint = endpoint @service = service end def get_user_id_from_credentials(username, password) soap = wsdl.create_rpc_driver response = soap.GetUserID(:username => username, :password => password) soap.reset_stream response.getUserIDResult end private def wsdl SOAP::WSDLDriverFactory.new("http://#{@endpoint}/services/#{@service}.asmx?WSDL" end end |
By creating a “factory” with the services’ WSDL, you can easily set things up for remote procedure calls (i.e. GetUserID(username, password)). What’s even nicer is that you can parse the response by chaining methods together. In this case, it put me right inside the response, where I only needed to call one level of nested XML (response.getUserIDResult). But if this were nested deeper, I’d just keep calling the methods that map to the XML nodes until I got to what I wanted. And of course, I could then write any Ruby code to do what I needed to do, but the point is it’s automatically method-like access, which is nice (think of Builder).
So, once you write your “wrapper” class, you’re ready to go.
1 2 3 4 5 6 7 8 9 10 11 | class SomeDotNetWrapperController < ApplicationController def store_other_id raise InvalidCredentials if params[:username].blank? || params[:password].blank? service = SomeDotNetWrapper.new('http://example.com', 'authentication') other_id = service.get_user_id_from_credentials(params[:username], params[:password]) current_user.update_attribute(:other_id, other_id) unless other_id.to_i == 0 rescue InvalidCredentials # ... end end |
I’m sure there are a lot of different approaches, but this seemed the easiest to me. I had somewhat of a difficult time finding a solid solution online for easily consuming .NET SOAP services, so I decided to resort back to the standard library, as generally every language has support for this sort of thing. Anyway, maybe someone else with the same needs will find this useful.

robert Wednesday, 25 Jun, 2008 Posted at 05:15PM
Just dropping a note saying you helped at least one person.
Thanks for the great post. Helps a SOAP newb like me figure out what the hell he’s doing when a client decides to ask for integration with ancient technology ;)
Jacek Becela Saturday, 04 Oct, 2008 Posted at 10:59AM
You helped at least two people :) Thanks a lot!
Soleone Tuesday, 11 Nov, 2008 Posted at 01:27AM
Now make that three! This will be quite useful to demo IRB goodness to Ruby newcomers.
Brian Thursday, 15 Jan, 2009 Posted at 04:44PM
And you’re off to four!! I’m getting addicted to Ruby, and Web Services clients – very fun to write and fairly easy to learn when your new to both programming and web services.
Emil Thursday, 05 Feb, 2009 Posted at 03:21AM
Wow, that is easy! I have only tried soap4r before, where you had to generate (!) a lot of files. This is the way it should be!
Steve Jorgensen Wednesday, 04 Mar, 2009 Posted at 07:32PM
Yup – years later, you helped me as well.
Nate Murray Friday, 13 Mar, 2009 Posted at 02:17PM
You can view the raw XML by calling this on your driver:
Adam Elliot Monday, 11 May, 2009 Posted at 03:00AM
Ahh this is exactly what I needed. Nice and simple!
Thanks!
Gishu Tuesday, 28 Jul, 2009 Posted at 07:59AM
me = #9
Great post. Works as advertised. Thanks for taking the time to write this down.
Teoulas Wednesday, 16 Sep, 2009 Posted at 04:31AM
Thanks for the article! Really helpful.
rabbit Thursday, 15 Oct, 2009 Posted at 04:28PM
Thank you. Helped me
Igor Minar Friday, 30 Oct, 2009 Posted at 02:27PM
You shouldn’t call create_rpc_driver during each lookup as this will dynamically construct the driver from WSDL. You should do that in the initialize method only once then reuse the driver in subsequent calls.
Ryan Friday, 30 Oct, 2009 Posted at 07:26PM
@Igor Minar -
I’ve realized that since writing this post, but thanks for the tip nonetheless.
Leo Tuesday, 01 Dec, 2009 Posted at 11:01AM
Nice post. It is nice to see another WVU graduate( especially CPE and EE graduate) doing ruby on rails.
Hoopla Thursday, 03 Dec, 2009 Posted at 04:59PM
REST is NOT cool and SOAP does NOT suck.
If your development environment supports it, you can use exposed SOAP-based web services like they are local functions within minutes after downloading the WSDL.
If your development environment supports it, you can expose SOAP-based web services within minutes after writing the first server method.
In REST, you have to handle lot’s of things by yourself, which increases the risk for bugs and problems. Yeah, SOAP has some overhead, but it is not that much more than REST and if you want speed, you should go binary.
There is a lot of crap going round from people that seem to have nothing else to do than recurse XML-trees. Me, I have to make a living and satisfy customers demands.
I have implemented enough REST to have it up to my neck.
And why the heck call it REST?
It’s just a frickin GET for a frickin XML file!
CALL IT GET!
bumblebumble
Hoopla Thursday, 03 Dec, 2009 Posted at 04:59PM
REST is NOT cool and SOAP does NOT suck.
If your development environment supports it, you can use exposed SOAP-based web services like they are local functions within minutes after downloading the WSDL.
If your development environment supports it, you can expose SOAP-based web services within minutes after writing the first server method.
In REST, you have to handle lot’s of things by yourself, which increases the risk for bugs and problems. Yeah, SOAP has some overhead, but it is not that much more than REST and if you want speed, you should go binary.
There is a lot of crap going round from people that seem to have nothing else to do than recurse XML-trees. Me, I have to make a living and satisfy customers demands.
I have implemented enough REST to have it up to my neck.
And why the heck call it REST?
It’s just a frickin GET for a frickin XML file!
CALL IT GET!
bumblebumble
flex Thursday, 31 Dec, 2009 Posted at 04:41PM
you might wanna try savon: http://github.com/rubiii/savon
Charles Thursday, 28 Jan, 2010 Posted at 05:03PM
@Hoopla You don’t know what you’re talking about.
Daren Saturday, 06 Feb, 2010 Posted at 06:37PM
@Hoopla you must be kidding me. for me, i tried savon after reading this post and comments and it’s working fine for me. did anyone take a look at the source of soap4r? it’s a mess.
Rob Friday, 25 Jun, 2010 Posted at 06:58AM
@Hoopla i agree you don’t have a clue, you’ve probably never even experieced the warm fuzzy feeling when you find a web service thats restful.
soap does suck hugely, lazy use soap its all done for you, then those of us who write proper languages have to pick up the pieces to integrate with bloated corporate crap. REST makes its simple everything has the same standard methods and request types you don’t have to download a massive WSDL to find out what the service does.
Try and integrate with Ebay its a nightmare!!!
@flex, @Daren I also use Savon, a very well written gem, soap4r is poorly documented and yes a mess!
leo chan Friday, 02 Jul, 2010 Posted at 05:36PM
How do you call a soap method that accept complex type in the params instead of simple string type? I tried to do that in a hash but didn’t seem to work.
Sid M Friday, 03 Dec, 2010 Posted at 09:24AM
+1 …very helpful, thank you Ryan!
@Hoopla – you remind me of the many old-school VB developers I am forced to work with on a regular basis. As illustrated by your post, you just don’t ‘get’ it. (Sorry, couldn’t resist) ;-)
Anonym Wednesday, 21 Sep, 2011 Posted at 05:15PM
+1 saved soul