Hashrocket.com / blog

Large soap

You can build SOAP requests with HAML

posted on and written by in

Image 100x100 micah cooper

HAML can produce markup that looks terse, simple, and pleasant. SOAP requires markup can that look verbose, complex and unpleasant. If you combine the two and add just a touch of sugar, you can give your application some medicine that goes down quite smoothly. Let's explore.

If I'm making a soap request I usually have this markup from the documentation of the api.

Take that markup and save it as a fixture so you can test against it later.

spec/fixtures/<soap_service>/<operation>/xml

<soapenv xmlns="foo">
  <header>
    <security>
      <username value="bar"/>
      <password>
        baz
      </password>
    </security>
  </header>
  <soapbody>
    <foo:content>
      rem ipsum dolor sit amet
    </foo:content>
  </soapbody>
</soapenv>

So that's the xml. Let's see the HAML representation of the same thing:

!!! XML
%soapenv(xmlns="foo")
  %header
    %security
      %username(value="bar")/
      %password= password 
  %soapbody
    %foo:content rem ipsum dolor sit amet

Cleaner? Yeah? I think so too!

Be sure to test that your HAML returns your xml in the proper format.

Note about testing: HAML orders your attributes alphabetically so it's hard to do a direct == comparison on the two docs. One suggestion is to use Nokogiri in your tests.

Now let's actually use this all as we would in a class that calls the service:

require 'faraday'
require 'haml'

class SoapService

  def response
    Faraday.post(<url>, request_body)
  end 

  def request_body #returns the xml document for the body of the request
    #pass #self to haml_engine.render 
    #so your HAML can call all the methods 
    #in this SoapService class. (very convenient!).
    haml_engine.render(self) 
  end 

  def haml_engine
    Haml::Engine.new(request_file, { attr_wrapper: '"', format: :xhtml })
  end 

  def request_file #called in request body
    File.read("path/to/haml/file")
  end 

  def password #this method is called in the HAML document
    "baz"
  end

end

Now use this class like so:

SoapService.new.request_body

This will return:

<soapenv xmlns="foo">
  <header>
    <security>
      <username value="bar"/>
      <password>
        baz
      </password>
    </security>
  </header>
  <soapbody>
    <foo:content>
      rem ipsum dolor sit amet
    </foo:content>
  </soapbody>
</soapenv>

And that's it. I have found this to be a most pleasant way to build soap requests with ruby.

Posted in Development and tagged with Ruby, HAML, Soap