LoginSignup
2
2

More than 5 years have passed since last update.

Node.js + ExpressでSOAP通信するAPIを作ろう

Last updated at Posted at 2019-01-22

🔶はじめに

最初は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[準備編]

routerフォルダ配下に、test.jsファイルを作り、app.jsにパス等を記載します。

test.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の機能の一部です。ドキュメントを見ると、他にも色々と機能や設定があるようなので、試してみてはいかがでしょうか。

🔶参考

2
2
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
2