Ruby에서 SOAP를 사용하는 가장 좋은 방법은 무엇입니까?


91

제 고객이 타사 API를 Rails 앱에 통합 해달라고 요청했습니다. 유일한 문제는 API가 SOAP를 사용한다는 것입니다. Ruby는 기본적으로 REST를 위해 SOAP를 삭제했습니다. 그들은 분명히 Java-Ruby 브릿지와 함께 작동하는 Java 어댑터를 제공하지만 가능하면 모든 것을 Ruby로 유지하고 싶습니다. soap4r을 살펴 보았지만 평판이 약간 나쁜 것 같습니다.

그렇다면 SOAP 호출을 Rails 앱에 통합하는 가장 좋은 방법은 무엇일까요?

답변:


36

우리 soap/wsdlDriver는 실제로 SOAP4R 인 빌트인 클래스를 사용했습니다 . 느리지 만 정말 간단합니다. gems / etc에서 얻은 SOAP4R은 같은 것을 업데이트 한 버전입니다.

예제 코드 :

require 'soap/wsdlDriver'

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

그게 다야


37
이것이 "Dog Slow"인 이유 중 하나는 서비스에 연결할 때마다 프록시를 구축하기 때문입니다. wsdl2ruby를 사용하여 프록시를 영구적으로 빌드 한 다음 사전 생성 된 프록시를 호출하면 이러한 고통을 피할 수 있습니다.
Steve Weet

6
우리는 할 수 있지만 그것은 wsdl2ruby 등을 설치하는 것을 의미합니다. 때때로 개 슬로우는 괜찮습니다 :-)
Orion Edwards

1
Savon 용 프록시 클래스를 빌드해야하는 경우 SoapUI의 도움으로 즉시 soap 메서드를 빌드하는 kredmer의 접근 방식을 따라 메서드 이름을 채우고 사용자 지정 wsdl 파서를 빌드 할 필요가 없습니다. 모든 메소드를 메모리에 저장하는 대신 특히 많은 경우 파일에 쓸 수 있습니다.
데얀

3
04/2015 : Soap4r이 종료되고 웹 사이트가 다운되었습니다. 현재 Savon이 일반적인 선택 인 것 같습니다.
Puce 15.04.20

나는이 공간을 파고 들었고
Ghoti

170

저는 Ruby를 통해 SOAP 웹 서비스와 최대한 쉽게 상호 작용할 수 있도록 Savon 을 만들었습니다.
나는 당신이 그것을 확인하는 것이 좋습니다.


5
savon에 +1, soap4r을 bash는 것은 아닙니다. 그러나 나는 그것에 대해 정말 나쁜 경험을했습니다. 좋은 문서가 부족하고 너무 번거 롭습니다.
konung

1
좋은! 루비의 SOAP 세계는 내가 (18 개월 전에 ~) 이렇게 Soap4R를 사용했다 마지막 시간 이후 개선
madlep

누구든지 savon을 사용하여 saber api를 칠 수 있도록 도와 주시겠습니까? SOAP의 wsdl을 사용하여 메서드를 제공하는 코드가 있지만 savon을 xml 형식으로 사용하여 요청을 보낼 수 없습니다.
Jai Kumar Rajput


5

나는 또한 Savon 을 추천 합니다. 결과없이 Soap4R을 처리하는 데 너무 많은 시간을 보냈습니다. 기능이 크게 부족하고 문서가 없습니다.

Savon이 저에게 답입니다.



3

Savon을 사용하여 3 시간 이내에 제 물건을 작동 시켰습니다.

Savon 홈페이지의 Getting Started 문서는 따라 가기가 정말 쉬웠으며 실제로 제가 본 것과 일치했습니다 (항상 그런 것은 아닙니다)


2

에서 켄트 Sibilev Datanoise는 또한 레일 2.1 (이상)에 레일 ActionWebService 라이브러리를 이식했다. 이를 통해 자신의 Ruby 기반 SOAP 서비스를 노출 할 수 있습니다. 그는 브라우저를 사용하여 서비스를 테스트 할 수있는 스캐 폴드 / 테스트 모드도 있습니다.


2

승인 테스트를 위해 가짜 SOAP 서버를 만들어야 할 때 Ruby에서 SOAP를 사용했습니다. 이것이 문제에 접근하는 가장 좋은 방법인지는 모르겠지만 저에게 효과적이었습니다.

저는 Sinatra gem ( 여기서 Sinatra로 조롱 엔드 포인트를 만드는 방법에 대해 썼습니다 )을 서버에 사용하고 Nokogiri 를 XML 항목에 사용했습니다 (SOAP는 XML과 함께 작동합니다).

그래서 처음에는 SOAP 서버가 반환 할 미리 정의 된 답변을 넣은 두 개의 파일 (예 : config.rb 및 response.rb)을 만들었습니다. 에서 config.rb 나는 WSDL 파일을 추가하는 듯했으나 문자열로했다.

@@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>'

에서 responses.rb 나는 SOAP 서버가 서로 다른 시나리오에 돌려 보낼 응답을 넣어 샘플을 가지고있다.

@@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>"

이제 실제로 어떻게 서버를 생성했는지 보여 드리겠습니다.

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

이 정보가 도움이 되셨기를 바랍니다.



0

SOAP 메서드를 호출하기 위해 아래와 같은 HTTP 호출을 사용했습니다.

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")
*/

도움이되기를 바랍니다. 건배.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.