Tag: Savon

About a week ago rubiii has released the first beta of Savon 0.8. A lot of bugfixes, improvement and API changes have been addressed in the latest version. If you want to get used to the new API a good starting point is the Savon Guide.

One thing that should be noted right away, is that Savon 0.8 is not downwards compatible. Most code parts have been rewritten and Savon now offers an improved error handling, support for local wsdl documents and more flexibility on request methods. See the changelog for more information.

Shootout update

I have updated the examples used for the shootout to reflect the latest changes for Savon 0.8.beta3, Handsoap 1.1.7 and SOAP4R. I restructured the examples, removed dead services and added Bundler for gem dependencies. The examples run on MRI 1.8.7 and JRuby 1.5.2.

More Savon infrastructure

Some effort has been taken to make the day to day work with Savon even more pleasant. If you are working with RSpec, you can now test using Savon Spec.

If you are used to work with ActiveRecord models Savon Model will help integrating SOAP into your Rails projects.

Using a DB is a natural thing for a Rails developer. Since Rails is a database driven application framework, that does not come as a big surprise. But there are times where environmental constraints do not allow the freedom to use the weapon of choice…

Imagine a legacy Java SOA landscape that provides tons of webservices but does not permit access to a transaction DB. Sounds phoney? Ask your local J2EE consultant!

Working around this constraint, it would be great if one could just wire a SOAP service into Rails as a backing of model data. Using Rails without a database is a little bit tricky, especially if you don’t want to forego the power of ActiveRecord!

so why use Rails then?

There are a lot of people that would say “Why don’t you use Sinatra instead?”.

First of all, most Ruby developers know how to use Rails. The Rails community is large, lively and a great resource for knowledge. Features like REST come for free and nobody want’s to miss model validations. In general, Rails plugins are lazy programmers best friend!

working with ActiveForm

A simple way to get your SOAP backed noSQL model working with ActiveRecord::Validations is probably by using ActiveForm. It provides validations for non ActiveRecord models and is available on github.

It’s possible to remove all evidence of database connectivity. Just kick ActiveRecord from the list of Rails frameworks and re-add it as a gem (this step is not necessary, so you might skip it and work with Rails sqlite3 default):

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.

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.

The proxy style client of Savon is less code and provides a flexible API, especially looking at SOAP calls.

Using rspec to demonstrate the expected behavior of the clients results in two identical spec for getting a zip code of a concrete client implementation:

describe "Savon" do
it "should return the corrent zip code for a given bank" do
zip_code = Shootout::SavonBankCode.zip_code @bank_code
zip_code.should eql @zip_code
end
end
describe "Handsoap" do
it "should return the corrent zip code for a given bank" do
zip_code = Shootout::HandsoapBankCode.zip_code @bank_code
zip_code.should eql @zip_code
end
end

Compared to the spec, the code of the two implementations differs a great deal. The task at hand is to call the getBank method of the SOAP endpoint providing a blz (bank code) parameter and extracting the plz (zip code) value of the response.

Using the Handsoap client class defined above, sending the “invoke()” message to the Handsoap::Service will do the job:

The bank code parameter is assigned in the block, which yields a SOAP message object. The resulting XML document is wrapped and can be accessed using some predefined XML library. Handsoap enables you to choose between different types of XML parsers like REXML, ruby-libxml or nokogiri.

Savon’s proxy client on the other hand is dynamic and can be accessed directly with the name of the SOAP method and a block:

The block yields a SOAP request object for setting the payload or tweaking defaults like the SOAP header. Converting the response to a hash is a convenient way to access the desired result. The conversion is done using crack.

Both clients provide an interface to work with a WSDL. While the Handsoap WSDL support is hidden in some helper class, WSDLs are a first class citizen in Savon. The code for printing out the available SOAP actions looks like this: