2016-10-02

Soapforce使ってみた

Ruby製のSalesforce APIクライアントのSoapforceを使ってみました。名前の通り、SOAP APIで実装されています。

Ruby製の APIクライアントだとrestforceが有名だと思いますが、今回はバルク処理をどうしても行いたかったため、Soapforceを使ってみました。winter16でREST APIのSObject Treeが正式リリースされたので、そっちを使ってもOKですが…。

インストール&使い方

Gemfileに以下を記述してbundle install

gem 'soapforce'

使い方はこんな感じで

require 'soapforce'

client = Soapforce::Client.new
client.authenticate(username: ENV['SFDC_USERNAME'], password: ENV['SFDC_PASSWORD'])

query_result = client.query('SELECT id, name FROM Account')
query_result.records.each do |record|
  puts record.to_h
end

create_result = client.create('Account', [{name: 'hogehoge'}])
update_result = client.update('Account', [{id: create_result[:id], name: 'fugafuga'}])

Soapforceコードリーディング

Soapforceは内部でSavonというRubyのSOAP Clientを使っています。

こんな感じでWSDLを読み込ませてクライアントを作成して

@client = Savon.client(
    wsdl: @wsdl,
    soap_header: @headers,
    convert_request_keys_to: :none,
    convert_response_tags_to: @response_tags,
    pretty_print_xml: true,
    logger: @logger,
    log: (@logger != false),
    endpoint: @login_url,
    ssl_version: @ssl_version # Sets ssl_version for HTTPI adapter
    )

あとはcallメソッドを呼び出せばSOAPリクエストができるようになっています。

client.call(:login) do |locals|
  locals.message :username => 'hoge@example.com', :password => 'hogehoge'
end

ログインのSOAPリクエストはこんな感じのXMLになります。

<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:tns="urn:partner.soap.sforce.com" 
  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:ins0="urn:sobject.partner.soap.sforce.com" 
  xmlns:ins1="urn:fault.partner.soap.sforce.com">
  <env:Body>
    <tns:login>
      <tns:username>hoge@example.com/tns:username>
      <tns:password>hogehoge</tns:password>
    </tns:login>
  </env:Body>
</env:Envelope>

上記のRubyコード内のusername、passwordのシンボルキーは内部のXMLタグ名になっています。つまり、シンボル名が変われば中身のパラメータ名が変わります。

また、SOAPメッセージのデバッグはloggerパラメータをセットすればOK。

client = Soapforce::Client.new(:logger => Logger.new(STDOUT))

コードはSavonを使っているので、かなりシンプルで読みやすいです。client.rbがクライアントでresult.rbquery_result.rbsobject.rbでラッピングする構造となっています。

このエントリーをはてなブックマークに追加