Ruby, SOAP, and savon

I have to interact with a SOAP API to provision resources. This is a bit of a pain because A) I'm not very familiar with SOAP as a framework/protocol B) I'm still learning Ruby.

To help in my efforts, I opted to use the Ruby Gem Savon in part because it seemed really easy to use, and partly because it had a few more example snipets than alternatives.

The SOAP service to which I'm connecting first requires I authenticate with a username/password/apikey using the authenticateUser action. The return value for a successful authentication will be my authorization key that I then use for (up to 60 minutes) to call other API actions.

This is the code I was attempting to run (comments inline describe what I'm attempting).

require 'savon'

# Set variables
wsdl_url = 'https://server/api.asmx?WSDL'  
username = 'user123'  
password = 'password123'  
apikey   = 'pjEif938F23nsl38qND2'

# Configure client
client   = Savon.client(wsdl: wsdl_url, ssl_verify_mode: :none)

# Authenticate
authResponse = client.call(:authenticate_user, message: {  
  username: username,
  password: password,
  APIKey: apikey
})

# Set the Authkey to the auth response
authKey = authResponse.body[:authenticate_user_response][:authenticate_user_result]

puts authKey  

Seasoned users of Ruby/savon (which I'm currently not) will probably notice this problem (heck, anyone with eyes will see the syntax highlighting indicates something is different):

APIKey: apikey  

Due to either how savon or ruby deals with capital letters, the data sent to the server included the username and password, but no APIKey. After struggling a bit, I stumbled upon this StackOverflow article. After following the advice, and changing the input to a hash, everything works as expected:

# Authenticate
authResponse = client.call(:authenticate_user, message: {  
  'username' => username,
  'password' => password,
  'APIKey'   => apikey
})
Tagged in: Ruby, SOAP, API
comments powered by Disqus