Quelle est la meilleure façon d’utiliser SOAP avec Ruby?

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 abandonné SOAP en faveur de REST. Ils fournissent un adaptateur Java qui fonctionne apparemment avec le pont Java-Ruby, mais nous aimerions tout garder dans Ruby, si possible. J’ai cherché dans soap4r, mais il semble avoir une mauvaise réputation.

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

Nous avons utilisé la classe soap/wsdlDriver , 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 ça

J’ai construit Savon pour que l’interaction avec les services Web SOAP via Ruby soit aussi simple que possible.
Je vous recommande de le vérifier.

Nous sums passés de Handsoap à Savon.

Voici une série de billets de blog comparant les deux bibliothèques clientes.

Je recommande également Savon . J’ai passé trop de temps à essayer de gérer Soap4R, sans résultats. Big manque de fonctionnalité, pas de doc.

Savon est la réponse pour moi.

Essayez SOAP4R

  • SOAP4R
  • Premiers pas avec SOAP4R

Et je viens d’en entendre parler sur le podcast Rails Envy (ep 31):

  • Procédure pas à pas WS-Deathstar SOAP

Je viens de faire fonctionner mes affaires en 3 heures avec Savon.

La documentation de mise en route sur la page d’accueil de Savon était vraiment facile à suivre et correspondait réellement à ce que je voyais (pas toujours le cas)

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

J’ai utilisé SOAP dans Ruby quand j’ai dû créer un faux serveur SOAP pour mes tests d’acceptation. Je ne sais pas si c’était 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 nœuds d’extrémité avec Sinatra ici ) pour le serveur et aussi pour Nokogiri pour XML (SOAP fonctionne avec XML).

Donc, pour le début, j’ai créé deux fichiers (par exemple, config.rb et answers.rb) dans lesquels j’ai mis les réponses prédéfinies que le serveur SOAP renverra. Dans config.rb, j’ai mis le fichier WSDL, mais sous forme de chaîne.

 @@wsdl = ' ....... ' 

Dans answers.rb, j’ai mis des échantillons pour les réponses que le serveur SOAP renverra pour différents scénarios.

 @@login_failure = "    Invalid username and password  false    " 

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_ssortingng 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!

J’avais le même problème, je suis passé à Savon, puis je l’ai 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/soaprb/soap

J’ai utilisé l’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 ="    ITE2 topo #{job_name}   " @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 cela aide. À votre santé.