2

using Savon version 3.x (the current master branch found https://github.com/savonrb/savon).

currently to generate a soap request in savon 3 you define the body of the message as a hash, ex:

operation.body = {
  Search: {
    accountID: 23,
    accountStatus: 'closed'
  }
}

response = operation.call

from the hash, savon will generate the complete soap message xml (envelope, headers, etc..) and pass that message onto HttpClient to post the request to your soap endpoint.

instead of a hash, i'd like to be able to pass in a complete xml message as my request, ex: my_xml_request_message =' ..... lots more nested nodes, namespaces and tons of attributes, etc ..... '

it appears that body is sent to build to create the soap request, and is then posted by call: https://github.com/savonrb/savon/blob/master/lib/savon/operation.rb#L79

def call
  raw_response = @http.post(endpoint, http_headers, build)
  Response.new(raw_response)
end

so i thinking was to monkey patch? call to allow me to override build with my xml block, ex:

def call
  raw_response = @http.post(endpoint, http_headers, my_xml_request_message)
  Response.new(raw_response)
end

that's where we're getting stuck - it's not clear to me if my xml is getting created or posted correctly. or if this is the correct way to proceed...

thanks in advance for any help!

solidlight
  • 61
  • 5
  • so we came up with a monkey patch by overriding the call() method in Savon > Operation: `class Savon class Operation attr_accessor :raw_xml_message def call message = (raw_xml_message != nil ? raw_xml_message : build) raw_response = @http.post(endpoint, http_headers, message) Response.new(raw_response) end end end` then we are including a new method `def raw_xml_message` in our framework in cases where we don't want to define a has for `def body`. – solidlight Feb 01 '14 at 01:43
  • should this patch be added to Savon 3 master or is there a better solution? – solidlight Feb 01 '14 at 01:48

2 Answers2

1

I don't use Savon3 yet, because it's not stable yet. What you can do in v2 is:

client.call(:authenticate, xml: "<envelope><body></body></envelope>")

I suppose something similar will work in v3 as well. It existed in v1 and v2.

Steffen Roller
  • 3,464
  • 25
  • 43
  • hi. thanks for the reply. yes i got it working with v2. we've build out a framework using v3 because we like the approach savon is taking with the rewrite. so far everything has been working well, but we do want to pass in the full xml (and unfortunately savon's example_body method won't be able to generate a body() hash in this case). – solidlight Jan 31 '14 at 20:32
1

monkey patch solved our problem - so i think this is good answer for now. we're looking to add this solution to savon 3 master if possible, details: https://github.com/savonrb/savon/issues/546

 class Savon
  class Operation
    attr_accessor :raw_xml_envelope

    def call
      message = (raw_xml_envelope != nil ? raw_xml_envelope : build)

      raw_response = @http.post(endpoint, http_headers, message)
      Response.new(raw_response)
    end

  end
 end

more background:

we've built a webservices (SOAP & REST) testing framework using Savon for the soap backbone. in our framework we define a couple methods describing each wsdl operation, our use case is to allow usage of the savon body() method when wanting to define the xml body as a hash (as described by savon's example_body()) or to pass in the complete raw xml envelope - which we are able to do using raw_xml_envelope() method above via monkey patch.

solidlight
  • 61
  • 5