Search code examples
rubysavon

Ruby / Savon Model with dynamic URL


I'd like to make a Savon Model but pass the URL of the WSDL when I initialize a client. Something like this:

class MyService
  extend Savon::Model
  client :wsdl self.url

  def initialize(url)
    self.url = url
  end
end

Any idea how to achieve this?


Solution

  • client and operations are class-level methods(macros), so you just need to reference them with a self.class from inside the constructor.

    So, here is an example of a working dynamic MyService class that takes the url of the endpoint as well as which operations you want to perform, comma-separated...

    require 'savon' # I am assuming savon 2.4.0 here...
    
    class MyService
      extend Savon::Model
    
      def initialize(url, *operations)
        self.class.client wsdl: url
        operations.each { |operation| self.class.operations operation }
      end
    end
    
    url = "http://www.webservicex.net/stockquote.asmx?WSDL"
    service = MyService.new(url, :get_quote)
    response = service.get_quote(message: { symbol: "AAPL" })
    
    puts response.body[:get_quote_response][:get_quote_result]
    

    Sample output

    <StockQuotes><Stock><Symbol>AAPL</Symbol><Last>592.98</Last><Date>5/2/2014</Date><Time>11:55am</Time>     <Change>+1.50</Change><Open>592.89</Open><High>594.20</High><Low>589.71</Low><Volume>3406189</Volume><MktCap>510.8B</MktCap><PreviousClose>591.48</PreviousClose><PercentageChange>+0.25%</PercentageChange><AnnRange>388.87 - 599.43</AnnRange><Earns>41.727</Earns><P-E>14.17</P-E><Name>Apple Inc.</Name></Stock></StockQuotes>