#🔶はじめに
最初はtalendを使って、SOAP⇔REST変換するAPIを作ろうと思ったのですが、難しそうだったのでNode.jsのモジュールのnode-soapを使って、SOAP通信を行うREST APIを作ることにしました。
##🔷node-soap
SOAP通信を行うモジュールです。
WSDLファイルを読み込んで、SOAP通信を行うクライアントを作れます。
ドキュメントを読む限り、SOAPサーバーも作成できるらしいです。
node-soap
https://github.com/vpulim/node-soap
#🔶実装
まず、expressでスケルトンを作り、node-soapをインストールします。
スケルトンの作り方は以下を参照。
[Node.js + ExpressでREST API開発を体験しよう for Windows[準備編]]
(https://qiita.com/tamura_D/items/98bbd4a3143da960faf5#-%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E9%9B%9B%E5%BD%A2%E3%81%AE%E7%94%9F%E6%88%90)
routerフォルダ配下に、test.jsファイルを作り、app.jsにパス等を記載します。
const express = require('express');
const router = express.Router();
const soap = require('soap');
const wsdlUri = 'http://hogehoge/fuga?wsdl'; // WSDLファイルのURL
/* SOAPサービスに渡すパラメータを作成 */
let args = {
param01: 'hoge',
param02: 'fuga',
param03: 'piyo'
};
router.get('/', function(req, res, next) {
/* WSDLからSOAPクライアントを作成 */
soap.createClient(wsdlUri, {}, function(err, client) {
/* SOAPサービスの定義の確認 */
let describe = client.describe();
console.log(`🔴🔴describe🔴🔴\n${JSON.stringify(describe, replacer)}`);
/* リクエスト時にSOAPヘッダーのセット */
client.addSoapHeader({
HeaderName: {
testSoapHeader: 'hogehoge'
}
});
/* リクエスト時にHTTPヘッダーのセット */
client.addHttpHeader('x-hoge', 'fuga');
/* SOAPサービスの指定のメソッドへリクエスト */
client.HogeFugaPiyo(args, function(err, result, rawResponse, soapHeader, rawRequest) {
console.log(`😈😈err😈😈\n${err}`);
console.log(`🔶🔶result🔶🔶\n${JSON.stringify(result)}`);
console.log(`🔶🔶rawResponse🔶🔶\n${JSON.stringify(rawResponse)}`);
console.log(`🔶🔶soapHeader🔶🔶\n${JSON.stringify(soapHeader)}`);
console.log(`🔶🔶rawRequest🔶🔶\n${JSON.stringify(rawRequest)}`);
});
/* HTTP通信のリクエスト/レスポンス情報を取得 */
client.on('response', function(envelope, message) {
console.log(`🔷🔷message🔷🔷\n${JSON.stringify(message)}`);
res.send(message);
});
});
/* JSON.stringify()の循環構造対策 */
let seen = [];
let replacer = (key, value) => {
if (value != null && typeof value == "object") {
if (seen.indexOf(value) >= 0) {
return;
}
seen.push(value);
}
return value;
};
});
module.exports = router;
#🔶解説
##🔷SOAPクライアントを作成
WSDLファイルのURLを渡して、SOAP通信を行うクライアントを作成します。
ドキュメントには、WSDLファイルはローカルファイルでも良いと書かれています。
/* WSDLからSOAPクライアントを作成 */
soap.createClient(wsdlUri, {}, function(err, client) {
##🔷SOAPサービスの定義を確認
client.describe()
で、WSDLに書かれた定義情報を、JSONで出力します。
/* SOAPサービスの定義の確認 */
let describe = client.describe();
##🔷SOAP通信時のSOAPヘッダーをセット
client.addSoapHeader()
で、SOAPヘッダーをセットできます。
/* リクエスト時にSOAPヘッダーのセット */
client.addSoapHeader({
HeaderName: {
testSoapHeader: 'hogehoge'
}
});
上記の記載で、以下のようにSOAPヘッダーがセットされます。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://hogehoge/fuga" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/">
<soap:Header>
<HeaderName>
<testSoapHeader>hogehoge</testSoapHeader>
</HeaderName>
</soap:Header>
<soap:Body>
...(以下略)
##🔷SOAP通信時のHTTPヘッダーをセット
SOAP通信は、実際にはHTTP通信のPOSTメソッドで行われるが、client.addHttpHeader()
で、その際のHTTPヘッダーをセットします。
/* リクエスト時にHTTPヘッダーのセット */
client.addHttpHeader('x-hoge', 'fuga');
##🔷SOAPサービスの任意のメソッドをリクエスト
client.任意のメソッド名(args, function(err, result, rawResponse, soapHeader, rawRequest)
で、SOAPサービスのメソッドにリクエストを送ります。
リクエスト結果は、以下のように渡されます。
- result
- SOAPサービスからのレスポンス本文
- rawRespons
- SOAPサービスからのレスポンスとして渡されるXML
- soapHeader
- SOAPサービスからの、レスポンスのSOAPヘッダー
- rawRequest
- SOAPサービスへのリクエスト時に渡すXML
下の例では、HogeFugaPiyoメソッドにリクエストを投げています。
/* SOAPサービスの指定のメソッドへリクエスト */
client.HogeFugaPiyo(args, function(err, result, rawResponse, soapHeader, rawRequest) {
console.log(`😈😈err😈😈\n${err}`);
console.log(`🔶🔶result🔶🔶\n${JSON.stringify(result)}`);
console.log(`🔶🔶rawResponse🔶🔶\n${JSON.stringify(rawResponse)}`);
console.log(`🔶🔶soapHeader🔶🔶\n${JSON.stringify(soapHeader)}`);
console.log(`🔶🔶rawRequest🔶🔶\n${JSON.stringify(rawRequest)}`);
});
##🔷HTTP通信のリクエスト/レスポンス情報を取得
client.on('response', function(envelope, message)
で、HTTP通信の全ての情報を、message
に出力します。
/* HTTP通信のリクエスト/レスポンス情報を取得 */
client.on('response', function(envelope, message) {
console.log(`🔷🔷message🔷🔷\n${JSON.stringify(message)}`);
res.send(message);
});
例えば、SOAPサービスからのレスポンス時に渡される、Cookie情報を取得したい場合は、message.headers['set-cookie']
で取得できます。
##🔷未解決
今回はcreateClient
という同期処理のメソッドを使いましたが、createClientAsync
という非同期処理のメソッドもあります。
しかし、試してみたところTypeError: callback is not a function
が出て、うまく実装できませんでした。
一応、調べてみると、色々なQ&Aサイトに同様の質問は上がってましたが、どこも解決方法は書かれていませんでしたので、今回は使わないので諦めました。
#🔶まとめ
このように、node-soapを使えば、「SOAP通信はXMLのやりとりで処理を行う」くらいの知識しかなくても、簡単にSOAP通信を行うREST APIを作る事ができます。
今回のサンプルは、node-soapの機能の一部です。ドキュメントを見ると、他にも色々と機能や設定があるようなので、試してみてはいかがでしょうか。
#🔶参考