概要
前回に引き続き、Node.jsからSQLRPG(ILE)を呼び出してJSON形式でデータを取得し、ブラウザに表示するプログラムを作成します。
本記事ではNode.js実装とその実行結果について解説します。
前提条件
- Node.jsがインストール済み
- itoolkitがインストール済み
itoolkitのインストール方法については、【IBM i × Node.js】itoolkit入門にて解説しています。
処理概要
IBM i 上の RPG プログラムを呼び出し、JSON形式のデータを取得してブラウザに表示する処理です。
- HTTPサーバーを立てて、リクエストを受け付ける
- SSH経由で IBM i に接続し、RPGプログラム(SQLTEST1)を呼び出す
- RPGから返ってきた XML形式の結果を JSON文字列に変換
- 変換した JSON をブラウザに返す
Node.jsプログラムの作成
サンプルソース
const http = require('http');
const { Connection, ProgramCall } = require('/home/TESTUSER/node_modules/itoolkit');
const { XMLParser } = require('/home/TESTUSER/node_modules/fast-xml-parser');
http.createServer((req, res) => {
const connection = new Connection({
transport: 'ssh',
transportOptions: { host: 'IPアドレス', username: 'ユーザーID', password: 'パスワード' },
});
//RPG呼出し設定
const program = new ProgramCall('SQLTEST1', { lib: 'TESTLIB' });
program.addParam({ name: 'JSONRESULT', type: '5000A', io: 'out', });
connection.add(program);
//RPG実行 レスポンス処理
connection.run((error, xmlOutput) => {
if (error) {
console.error("ERROR:", error);
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('Error: ' + error.message);
return;
}
// xmlOutput表示(確認用)
console.log('xmlOutput log ;', xmlOutput);
//xml→JSON文字列変換
const parser = new XMLParser();
let jsonString = '{}';
try {
const parsed = parser.parse(xmlOutput);
jsonString = parsed?.myscript?.pgm?.parm?.data || '{}';
// jsonString表示(確認用)
console.log("jsonString log : " ,jsonString);
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
res.end(jsonString);
} catch (parseError) {
console.error("XML parse error:", parseError);
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('Failed to parse XML output');
return;
}
});
}).listen(59999, () => {
console.log('Server run:59999');
});
要点 ここからソース解説
1. RPGプログラムの呼び出し方法
itoolkitライブラリを使用して、IBM i上のRPGプログラム(TESTLIB/SQLTEST1)をNode.jsから呼び出します。
const connection = new Connection({
transport: 'ssh',
transportOptions: { host: 'IPアドレス', username: 'ユーザーID', password: 'パスワード' },
});
const program = new ProgramCall('SQLTEST1', { lib: 'TESTLIB' });
program.addParam({ name: 'JSONRESULT', type: '5000A', io: 'out', });
connection.add(program);
2. RPG実行とレスポンス処理
connection.run()でRPGプログラムを実行し、結果をXML形式で受け取ります。
エラーハンドリングも含めて処理を行います。
connection.run((error, xmlOutput) => {
if (error) {
// エラー処理
}
// XML出力確認
});
3. XML → JSON文字列への変換
fast-xml-parserライブラリを使用して、RPGから返されたXMLをパースし、必要なデータ部分(data)を抽出してJSON文字列として整形します。
const parser = new XMLParser();
const parsed = parser.parse(xmlOutput);
jsonString = parsed?.myscript?.pgm?.parm?.data || '{}';
4. HTTPレスポンスとして返す
RPGから取得したJSON文字列をHTTPレスポンスとして返します。
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
res.end(jsonString);
実行結果
1. 実行方法
QIBM iのシェル画面(QP2TERM)を起動します。
CALL QP2TERM
Node.jsのプログラムを実行します。
今回は/home/TESTUSERにファイルを作成したので、以下のようになります。
node /home/TESTUSER/callrpg.js
2. ブラウザ画面での確認
ブラウザを起動し、以下のようにURLを実行します。
http://IPアドレス:59999
3. ログの確認
xmlOutput(XML形式)ログ例:
xmlOutput log ; <?xml version='1.0'?><myscript><pgm name='SQLTEST1' lib='TESTLIB' error='fast'>
<parm name='JSONRESULT' io='out'>
<data type='5000A' name='JSONRESULT'>[{"TKOKCD":"0001","TKOKKJ":"テスト1"},{"TKOKCD":"0002","TKOKKJ":"テスト2"}]</data>
</parm>
<success><![CDATA[+++ success S11162 SQLDEMO1 ]]></success>
</pgm>
</myscript>
jsonString(JSON形式)ログ例:
jsonString log : [{"TKOKCD":"0001","TKOKKJ":"テスト1"},{"TKOKCD":"0002","TKOKKJ":"テスト2"}]
つまづいたポイント
1. SQLRPGのコンパイルコマンド
今までFFRPGやSQLRPGを書く機会がなかったため、SQLRPGのコンパイル自体が初めてでした。SQLRPGには専用のコンパイルコマンドがあることを知り、以下のように実行しました。
CRTSQLRPGI OBJ(TESTLIB/SQLTEST1) SRCFILE(TESTLIB/QRPGLESRC) SRCMBR(SQLTEST1) OBJTYPE(*PGM) DBGVIEW(*SOURCE)
2. ライブラリの追加
SQLRPGで参照するファイルのライブラリが実行ライブラリリストに含まれていないと、実行時にエラーとなります。
対処法として以下の方法があります:
- RPG内で外部プロシージャを使用して、ADDLIBLEを実行
今回はこちらの方法を採用しました。 - Node.js→CL→RPGの流れでADDLIBLEを実行
こちらの方法は別記事にて解説しています。
Node.jsからRPGIIIの呼び出し
3. xml→JSON文字列変換
RPGから返されるデータはXML形式のため、Node.js側で扱いやすくするにはJSONへの変換が必要です。
今回は以下の流れで処理しました:
- RPG内でJSON文字列を生成
- XML形式でNode.jsに返却
- Node.jsでfase-xml-parserを使ってXMLをパース
- JSON文字列を抽出して必要なデータを取得
RPGとNode.jsではデータフォーマットが異なるため、形式変換のステップがデータ連携において重要になります。
まとめ
普段は固定フォーマットのRPGを使用しているため、SQLRPGの記述やコンパイルは初めての経験でした。また、Node.jsに触れるのも今回が初めてでしたが、実際に手を動かしてみることでNode.jsとSQLRPGの連携が可能であること、そして形式変換(XML→JSON)の重要性を実感できました。
この記事が、「オープン系は初めて」というIBM i技術者の方々にとって、少しでも参考になれば嬉しいです。
参考サイト
JBCC株式会社 IBM Powerコラム
Node.jsでWebアプリを作ってみよう
chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://www.jbcc.co.jp/products/files/ibmpowercolumn202204_Nodejs.pdf
Node.js iToolkit ドキュメント
https://nodejs-itoolkit.readthedocs.io/en/latest/index.html
当記事の著作権はIBMに帰属します。
詳細はこちらを参照ください。
