LoginSignup
2
5

More than 5 years have passed since last update.

Node.jsでSOAP通信する際の細かい設定

Last updated at Posted at 2018-11-02

はじめに

仕事で他サービスのAPIを呼び出す際に、SOAP通信をおこなう必要があったのでそのノウハウを記事にしました。

使用したライブラリは node-soap です。
基本的には、README を参考に実装しています。

Node.js で SOAP 通信をおこなう

SOAP client の生成


import * as soap from 'soap';

/***** 中略 *****/

  const client = await soap.createClientAsync(wsdlPath, options);

公式だと、以下の形でクライアントを生成しています。
私が利用したAPIでは、定められたメソッドを順番に呼び出す必要があったので非同期処理で実装をおこなっています。

// README
soap.createClient(url, function(err, client) {
  client.MyFunction(args, function(err, result) {
    console.log(result);
  });
});

// README
soap.createClientAsync(url).then((client) => {
  return client.MyFunctionAsync(args);
}).then((result) => {
  console.log(result);
});

API のメソッドを呼び出す

const fisrtResult = await client.MyFunctionAsync(firstArgs, firstOptions, firstHeader);
const secondResult = await client.MyFunction2Async(secondArgs, secondOptions, secondHeader);

client.methodAsync を利用した場合、返却される結果は [result, rawResponse, soapHeader, rawRequest] の形の配列となります。

取得結果を利用する場合は firstResult[0]、送信したタグを確認したい場合は firstResult[3] を参照します。

SOAP の際のパラメータについて

node-soap では様々なパラメータをセットして通信をおこなうことができます。

soap.createClientAsync でセットされる options は、WSDL に関する設定をすることができます。
useEmptyTag などがその一例となります。

const wsdlOptions = {
  useEmptyTag: true,
}

複数の namespace を使用する場合にはオプションを以下のようにすることで実現できる、との情報を見つけましたが、筆者の環境では動きませんでした。
namespace の設定は後述します。

const wsdlOptions = {
  overrideRootElement: {
   namespace: 'xmlns:tns',
   xmlnsAttributes: [{
     name: 'xmlns:ns2',
     value: "http://example.com/xxx/xxx",
   }, {
     name: 'xmlns:ns3',
     value: "http://example.com/xxx/xxx",
   }]
 },
}

次に、メソッドに渡すパラメータについて確認します。
client.MyFunctionAsync には firstArgs でパラメータを、 firstHeader で Cookie 情報を渡しました。今回、 firstOptions は使用しませんでした。
(* Cookie は利用した API の要件です。)

パラメータは、オブジェクト形式で渡します。

const Args1 = {
  tag: 'value',
}

const Args2 = {
  tag: {
    attributes: {
      key: 'key',
      value: 'value',
    },
  },
}

上記のオブジェクトを引数として渡すと、 Args1, Args2 はそれぞれ、下記の形になります。

// Args1
<tag>value</tag>

// Args2
<tag key="key" value="value"></tag>

タグの値を配列にすることで、親タグ内に複数の同じタグを並行して設定することができます。

const Params = [
  {
    key: 'key1',
    value: 'value1',
  },
  {
    key: 'key2',
    value: 'value2',
  },
];
<parent>
  <children key="key1" value="value1"></children>
  <children key="key2" value="value2"></children>
</parent>

namespace を拡張する

client を生成した後に、下記の処理をおこなうことで namespace を拡張できます。

client.wsdl.definitions.xmlns.ns2 = 'http://example.com/xxx/xxx';
client.wsdl.definitions.xmlns.ns3 = 'http://example.com/xxx/xxx';
client.wsdl.xmlnsInEnvelope = client.wsdl._xmlnsMap()

タグを namespace から引用したい場合、下記の形にすれば利用できました。

const Args1 = {
  "ns2:tag": 'value',
}

const Args2 = {
  "ns3:tag": {
    attributes: {
      key: 'key',
      value: 'value',
    },
  },
}

おわりに

SOAP 自体の知識が乏しかったため、実装に難航しました。
また、 node-soap 自体は Cookie を利用したセッションの管理には対応していないようなので、その部分は別に実装することになりました。

レスポンスのヘッダーは client.lastResponseHeaders['set-cookie'] で取得することができます。

不明点、不備などがありましたらコメントいただけますと幸いです。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5