Quelle est la meilleure façon d'utiliser du savon avec du rubis?

Un de mes clients m'a demandé d'intégrer une API tierce dans leur application Rails. Le seul problème est que L'API utilise SOAP. Ruby a essentiellement laissé tomber le savon en faveur du repos. Ils fournissent un adaptateur Java qui fonctionne apparemment avec le Pont Java-Ruby, mais nous aimerions tout garder dans Ruby, si possible. J'ai regardé dans soap4r, mais il semble avoir une réputation légèrement mauvaise.

Alors, quelle est la meilleure façon d'intégrer les appels SOAP dans une application Rails?

88
demandé sur jcoby 2008-09-02 22:46:09

10 réponses

Nous avons utilisé la classe soap/wsdlDriver intégrée, qui est en fait SOAP4R. C'est un chien lent, mais vraiment simple. Le SOAP4R que vous obtenez de gems / etc est juste une version mise à jour de la même chose.

Exemple de code:

require 'soap/wsdlDriver'

client = SOAP::WSDLDriverFactory.new( 'http://example.com/service.wsdl' ).create_rpc_driver
result = client.doStuff();

C'est à peu près tout

35
répondu Orion Edwards 2014-03-20 05:11:52

J'ai construit Savon pour rendre l'interaction avec les services web SOAP via Ruby aussi facile que possible.
Je vous recommande de vous y référer.

163
répondu rubiii 2012-11-22 14:10:57

Nous sommes passés de Handsoap à Savon.

Voici une série d'articles de blog comparant les deux bibliothèques clientes.

14
répondu phoet 2010-01-18 18:42:49

Je recommande également Savon . J'ai passé trop d'heures à essayer de faire face à Soap4R, sans résultats. Grand manque de fonctionnalité, pas de doc.

Savon est la réponse pour moi.

6
répondu brunetton 2018-04-09 21:41:55

Essayez SOAP4R

Et je viens d'en entendre parler sur les Rails Envy Podcast (ep 31):

4
répondu Jason Navarrete 2008-09-02 23:28:09

Je viens de faire fonctionner mes affaires dans les 3 heures en utilisant Savon.

La documentation de démarrage sur la page D'accueil de Savon était vraiment facile à suivre-et correspondait en fait à ce que je voyais (pas toujours le cas)

4
répondu ChrisW 2011-05-26 14:36:24

Kent Sibilev de Datanoise avait également porté la bibliothèque Rails ActionWebService sur Rails 2.1 (et au-dessus). Cela vous permet d'exposer vos propres services SOAP basés sur Ruby. Il dispose même d'un mode échafaudage/test qui vous permet de tester vos services à l'aide d'un navigateur.

2
répondu Philippe Monnet 2009-07-30 17:47:11

J'ai utilisé SOAP dans Ruby quand j'ai dû faire un faux serveur SOAP pour mes tests d'acceptation. Je ne sais pas si c'est la meilleure façon d'aborder le problème, mais cela a fonctionné pour moi.

J'ai utilisé Sinatra gem (j'ai écrit sur la création de points de terminaison moqueurs avec Sinatra ici) pour le serveur et aussi Nokogiri pour les choses XML (SOAP travaille avec XML).

Donc, pour le début, j'ai créé deux fichiers (par exemple config.rb et les réponses.rb) dans lequel j'ai mis le prédéfinies réponses que le serveur SOAP retournera. Dans config.rb j'ai mis le fichier WSDL, mais comme une chaîne.

@@wsdl = '<wsdl:definitions name="StockQuote"
         targetNamespace="http://example.com/stockquote.wsdl"
         xmlns:tns="http://example.com/stockquote.wsdl"
         xmlns:xsd1="http://example.com/stockquote.xsd"
         xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
         xmlns="http://schemas.xmlsoap.org/wsdl/">
         .......
      </wsdl:definitions>'

Dans réponses.rb j'ai mis des échantillons pour les réponses que le serveur SOAP retournera pour différents scénarios.

@@login_failure = "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <LoginResponse xmlns="http://tempuri.org/">
            <LoginResult xmlns:a="http://schemas.datacontract.org/2004/07/WEBMethodsObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <a:Error>Invalid username and password</a:Error>
                <a:ObjectInformation i:nil="true"/>
                <a:Response>false</a:Response>
            </LoginResult>
        </LoginResponse>
    </s:Body>
</s:Envelope>"

Alors maintenant, laissez-moi vous montrer comment j'ai créé le serveur.

require 'sinatra'
require 'json'
require 'nokogiri'
require_relative 'config/config.rb'
require_relative 'config/responses.rb'

after do
# cors
headers({
    "Access-Control-Allow-Origin" => "*",
    "Access-Control-Allow-Methods" => "POST",
    "Access-Control-Allow-Headers" => "content-type",
})

# json
content_type :json
end

#when accessing the /HaWebMethods route the server will return either the WSDL file, either and XSD (I don't know exactly how to explain this but it is a WSDL dependency)
get "/HAWebMethods/" do
  case request.query_string
    when 'xsd=xsd0'
        status 200
        body = @@xsd0
    when 'wsdl'
        status 200
        body = @@wsdl
  end
end

post '/HAWebMethods/soap' do
request_payload = request.body.read
request_payload = Nokogiri::XML request_payload
request_payload.remove_namespaces!

if request_payload.css('Body').text != ''
    if request_payload.css('Login').text != ''
        if request_payload.css('email').text == some username && request_payload.css('password').text == some password
            status 200
            body = @@login_success
        else
            status 200
            body = @@login_failure
        end
    end
end
end

J'espère que vous trouverez cela utile!

1
répondu Radu Rosu 2016-06-07 10:05:57

J'avais le même problème, je suis passé à Savon et je l'ai juste testé sur un WSDL ouvert (j'ai utilisé http://www.webservicex.net/geoipservice.asmx?WSDL ) et jusqu'à présent tout va bien!

Https://github.com/savonrb/savon

0
répondu Ecommerce-Technician 2014-10-08 17:37:11

J'ai utilisé un appel HTTP comme ci-dessous pour appeler une méthode SOAP,

require 'net/http'

class MyHelper
  def initialize(server, port, username, password)
    @server = server
    @port = port
    @username = username
    @password = password

    puts "Initialised My Helper using #{@server}:#{@port} username=#{@username}"
  end



  def post_job(job_name)

    puts "Posting job #{job_name} to update order service"

    job_xml ="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://test.com/Test/CreateUpdateOrders/1.0\">
    <soapenv:Header/>
    <soapenv:Body>
       <ns:CreateTestUpdateOrdersReq>
          <ContractGroup>ITE2</ContractGroup>
          <ProductID>topo</ProductID>
          <PublicationReference>#{job_name}</PublicationReference>
       </ns:CreateTestUpdateOrdersReq>
    </soapenv:Body>
 </soapenv:Envelope>"

    @http = Net::HTTP.new(@server, @port)
    puts "server: " + @server  + "port  : " + @port
    request = Net::HTTP::Post.new(('/XISOAPAdapter/MessageServlet?/Test/CreateUpdateOrders/1.0'), initheader = {'Content-Type' => 'text/xml'})
    request.basic_auth(@username, @password)
    request.body = job_xml
    response = @http.request(request)

    puts "request was made to server " + @server

    validate_response(response, "post_job_to_pega_updateorder job", '200')

  end



  private 

  def validate_response(response, operation, required_code)
    if response.code != required_code
      raise "#{operation} operation failed. Response was [#{response.inspect} #{response.to_hash.inspect} #{response.body}]"
    end
  end
end

/*
test = MyHelper.new("mysvr.test.test.com","8102","myusername","mypassword")
test.post_job("test_201601281419")
*/

J'espère que ça aide. Acclamation.

0
répondu Raja 2016-02-02 12:03:06