Question 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, quel est le meilleur moyen d'intégrer les appels SOAP dans une application Rails?


88
2017-09-02 18:46


origine


Réponses:


Nous avons utilisé le construit soap/wsdlDriver classe, 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


35
2017-09-03 00:27



j'ai construit Savon faire en sorte que l'interaction avec les services Web SOAP via Ruby soit aussi simple que possible.
Je vous recommande de le vérifier.


162
2018-01-18 18:54



Nous sommes passés de Handsoap à Savon.

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


14
2018-01-18 18:42



Je recommande aussi 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.


6
2018-03-12 11:05



Essayer SOAP4R

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


4
2017-09-02 19:05



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)


4
2018-05-26 14:36



Kent Sibilev de La 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.


2
2017-07-30 17:47



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é la gemme de Sinatra (j'ai écrit sur la création de points d'extrémité moqueurs avec Sinatra ici) pour le serveur et aussi 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 = '<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 les réponses.rb J'ai mis des échantillons pour les réponses que le serveur SOAP renverra 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
2018-06-07 10:05



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'ici tout va bien!

https://github.com/savonrb/savon


0
2017-10-08 17:37



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 ="<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 cela aide. À votre santé.


0
2018-02-02 12:03