Savon Handsoap Shootout

Looking into The Ruby Toolbox there are currently two popular SOAP client libraries available. In this short article I am going to crunch the candidates Savon, which is currently the most “popular” library, and Handsoap which follows short after. Both are open source projects hosted on github.

Scope

This article won’t cover all facets of both libraries. I concentrate on the features that are relevant for integrating a Ruby SOAP client into our particular SOA platform. That platform is commonly based on Java SOAP services based on frameworks such as CXF and Axis providing interfaces to internal business logic.

Since this is not a complete feature list, it should show you at least how to work with the APIs and which client might be the best choice for yourself.

Requirements

Having lots of Java Guys around here, there is no great focus on things like beautiful API design or Ruby magic, the client should just work! Living in a Java environment, the SOAP client has to integrate smoothly with JRuby. Since a lot of Ruby libraries lack support for JRuby, we always have to monkey patch a lot of code to make it run on the JRE.

Examples

We refer to free, public SOAP services, so everyone can run the examples by themselves.

I’d love to see you review serviceproxy as well (http://github.com/jeremydurham/serviceproxy), since it predates both handsoap and savon, and takes a similar approach. It doesn’t support things like WSSE authentication, because it was build specifically for the needs of our company. Serviceproxy has been used with JRuby apps for the last ~2 years in production.

Also, nokogiri is available on JRuby 1.4, or libraries could choose to use hpricot as a parser (which is built using ragel and JRuby friendly) to keep performance up.

First off, you should probably include soap4r. At least mention it as
an option. It’s the grand old man of soap clients for Ruby, and if
you’re looking for a reflection-based client, it’s fairly advanced.

While inheritance is a base concept of object oriented programming,
it’s usually better to use delegation instead. For not being stuck
on the API of the Handsoap::Service class, one would wrap things up
into some other class or module, creating more code than necessary.

In general I agree on this sentiment, but in this case I don’t think
it should carry much weight. Services are glue code, and so they
depend strongly on the API, no matter which implementation style you
use. I don’t really think it’s realistic to think that such code could
ever be reused in any other context. So that makes it a moot point.
There’s of course the matter of code reuse within the constraints of
the library and there is testing, but Ruby has such powerful
capabilities to get around this, that I don’t really see it as a
practical problem. You can stub out the http driver during testing.
There’s even a test-driver for the purpose.

Regarding WSDL parsing:

The WSDL parser is really just sugar on top for the Handsoap project.
It’s not used during runtime. For most development, you should really
use soapUI instead. That probably goes the same for Savon btw., but I
think you should mention this awesome project, since way too few
people are aware of its existence.

Regarding authentication:

Handsoap is quite deliberate about going low level. It might seem like
a bit more work (and it is), but it makes it easier to code around
quirky server side implementations in an orderly manner. Personally I
think that the level of abstraction chosen in Handsoap is perfect, but
that’s perhaps a subjective matter. Handsoap provides
wrappers/adapters over the XML parsing and HTTP libraries instead,
which allows the user to work with these in a uniform way, regardless
of the underlying gem. I think that’s a very powerful tool.

Finally, Handsoap has support for asynchronous services, through Event
Machine. It’s probably a bit of an edge case, but for those that need
it, it’s a powerful feature worth mentioning.