RPG開発者のためのIBM i モダナイゼーション入門!
RDi とWeb APIで新しい開発の世界を楽しもう - 第 8 回 -
はじめに
出村:「今回はいよいよ最終回です。ここまで、RDiの使い方からWeb API構築までいろいろな事を学んできましたね。前回はDataBaseテーブルを照会するWeb APIをILE RPGで作成しました。今回はクライアントから与えるデータをもとにDataBaseテーブルを追加・更新するWeb APIをILE RPGで作成してみましょう。加えて、RDiによるWeb APIのデバッグも行いますのでRDiとWeb APIの掛け算となります。これまでの集大成となるような回になります。」
松田:「もう最終回なんですね...。始まってしまうとあっという間でした。今回は、Web APIを通じてDataBaseの更新や、RDiでのデバッグですね。RDiでのデバッグは第 4 回の記事が参考になりますね。」
渡邊:「まさに今回はこれまで学んだ要素すべてが詰まっていると思います。早速始めていきましょう!」
ILE RPGの概要
出村:「今回作成するREST APIのHTTPリクエストと、その結果として得られるレスポンスは以下の通りです。少し解説すると、これまで使用してきた物理ファイル【BDSYAINP】に対し新規でデータを追加または更新します。つまり、リクエストボディーと呼ばれるJSON形式の文書内に、追加・更新したいデータを、該当する物理ファイルのフィールド定義を参照しながら記述します。これを外部から受け取りDBを更新するILE RPGプログラムを記述し、APIとして利用可能にします。APIサーバーとしてのILE RPGプログラムは、JSONの【syaibn】にセットされた値をキーとしてDBを検索し、存在しない場合は追加、存在する場合は更新します。
物理ファイルの定義や物理ファイル上のデータの準備は第 7 回の記事を参照してください。今回使用するILE RPGのソースは、SAVFファイルとして添付していますので活用して下さい。」
■HTTPリクエストの例

■HTTPレスポンス データ追加の時

■HTTPレスポンス データ更新の時

■プログラムの内容
*社員情報の追加・更新
*あくまでもサンプルのため、必要に応じてご変更下さい。
HPGMINFO(*PCML:*MODULE:*DCLCASE)
FBDSYAINP UF A E K DISK PREFIX(SY) 社員マスタ
D*パラメータ
*HTTP STATUS
D resStatus S 10I 0 HTTP STATUS
* JSONを想定したデータ構造 REQUEST BODY
D REQ DS QUALIFIED
D syaibn 4P 0 社員番号
D name 30A 社員名
D kana 20A 社員名カナ
D email 64A メールアドレス
D*その他変数
D SYAIBN S 4P 0 社員番号
*エントリー・パラメータ
C *ENTRY PLIST
C PARM REQ (I)
C PARM resStatus (O)
C
C MONITOR
C
C Z-ADD REQ.syaibn SYAIBN
C SYAIBN CHAIN BDSYAINP
C IF %FOUND
C*レコードを更新
C MOVEL REQ.name SYSYAINM
C MOVEL REQ.kana SYSYAIKN
C MOVEL REQ.email SYMAILMA
C UPDATE BDSYAINR
C Z-ADD 200 resStatus 200 OK
C ELSE
C*レコードを追加
C CLEAR BDSYAINR
C Z-ADD REQ.syaibn SYSYAIBN
C MOVEL REQ.name SYSYAINM
C MOVEL REQ.kana SYSYAIKN
C MOVEL REQ.email SYMAILMA
C WRITE BDSYAINR
C Z-ADD 201 resStatus 201 CREATED
C ENDIF
C*エラー
C ON-ERROR *ALL
C Z-ADD 500 resStatus 500 SERVER ERROR
C ENDMON
C
C SETON LR
C RETURN
松田:「ソースの中身を見てみると、前回のDB照会とは異なる点がありますね!例えば、今回はF仕様書のファイルタイプがU(更新)になっていますね。」
渡邊:「さらに、更新するために既存ファイルへデータ追加が必要なので、ファイル追加項目にAが入っていますね。」

出村:「その通りです。DBを照会するか更新するかで準備すべきプログラム内容は異なるので、API作成以前にプログラムの違いもチェックしておく必要がありますね。
また、HTTPリクエストには、今回初めて登場した【リクエストボディー】が含まれています。【リクエストボディー】は分かりますか?」
渡邊:「下記画像のように、HTTPリクエストのヘッダーの次にくるデータのことですね。」
出村:「そうです。そもそも今回のリクエストの内容で前回と大きく違うのはHTTPメソッドが【GET】=参照ではなく、【POST】=追加・更新になっている点です。【POSTメソッド】を使う場合は、【リクエストボディー】をAPIサーバーへ送ることが出来ます。
リクエストは【ヘッダー】と【ボディー】という形で分けられます。今回は下記画像のようにヘッダーの【Content-Type】にapplication/jsonをセットすることで【リクエストボディー】にJSON文書を使うことを宣言しています。【ボディー】にはJSON文書でデータを記述します。注意点として、文字コードはUTF-8で記述する必要があります。」

出村:「ILE RPGのプログラムは、リクエストボディーのJSONと同じキー名のサブフィールドを持つデータストラクチャ(以降DS)を準備する必要があります。このプログラムでは、【REQ】というDSにJSONに合わせたパラメータを記載し、エントリーパラメータとして定義しています。」
渡邊:「大文字・小文字も区別しないといけないので、ここではDSのサブフィールドもJSONに合わせて小文字で定義する必要があるのですか?」
出村:「その通りです。」



<使用するプログラムの内容>
プログラムのソースは下記よりダウンロード下さい。ターゲットリリースをV7R3M0に設定しているため、V7R3以上のマシン上で復元するようご注意ください。
SAMPLE2.SAVF
実際のソース内容
SYAPI02R.txt
ILE RPGを REST APIとして登録する
出村:「前回から引き続き、今回もREST APIをILE RPGで実装していきます。今回の目的は、既存DBの更新のため前回のDB照会とは少し異なる部分があります。更新の際のポイントもおさえていきましょう!」
<作業概要>
- プログラムオブジェクトの選択、サービス名の指定
- セキュリティ設定、パラメーターの使用方法、トリム設定
- サービス詳細設定、利用ユーザーIDの選択、ライブラリー・リスト設定
- WEBサービスから受け取る情報について、設定の最終確認
プログラムオブジェクトの選択、サービス名の指定
松田:「まずは、下記接続URLよりIBM Web Administration for i にてREST APIの作成からですね!」
※接続用URL
http://(サーバーのIPアドレス):2001/HTTPAdmin渡邊:「オブジェクトのパスには前回同様に、使用するILE RPGのパスを入力するのですね。」
出村:「今回、REST APIのサービスは【SYAPI02R】という名前で作成します。」
セキュリティ設定、パラメーターの使用方法、トリム設定
松田:「今回も使用するURLについてはHTTPSではなく、HTTPでしょうか。」
出村:「そうです。よって、【セキュア転送が必要】には【いいえ】が入ります。」
出村:「続いて、パラメータの設定に移ります。今回は、ILE RPGの中のエントリー・パラメーターの内容を拾ってきています。【REQ】はデータストラクチャーなので【struct】となっており、こちらはリクエスト内容なので【入力】にします。一方、【resStatus】は返す値になるので【出力】です。」
渡邊:「次はトリム・モードの設定ですね。」
出村:「今回はレスポンスボディーには値を返さないのでトリムは考慮不要、よって【なし】です。ちなみに、トリムとは、文字列の前後にある不要な空白や改行を削除する処理のことですね。」
サービス詳細設定、利用ユーザーIDの選択、ライブラリー・リスト設定
出村:「続いては、サービス詳細設定です。今回のHTTPメソッドは【POST】なので、【HTTP要求メソッド】もこれに合わせて【POST】にします。また、【許可されるメディア・タイプ】は【*JSON】しか受け取らないよう設定します。【入力パラメーター・マッピング】にもパラメーター名:REQがセットされていますね。【HTTP応答コード出力パラメーター】にはレスポンスステータス【resStatus】を入力します。前回のように、メソッドがGETの場合はそもそもリクエストボディー(実際のパラメーターの具体値)を受け取らないので、【許可されるメディア・タイプ】は考慮不要です。ですが、今回のメソッドはPOSTなので、リクエストボディーが存在するとのことで【許可されるメディア・タイプ】が有効になります。なので、今回【返される出力メディア・タイプ】は考慮不要です。」
渡邊:「このあたりは設定が細かくなってきますね。最初から、すべての内容を理解する必要はないので指定の通りに進めてみましょう。」
松田:「【サーバーのユーザーID】は前回同様、IWSサーバー作成時に指定したユーザー(IWSUSER)
第 5 回を使ってILE RPGのプログラムを実行するため、【サーバーのユーザーIDを使用】を選択します。IBM i 内のユーザーを使う場合は、【既存のユーザーID】を使います。デフォルトのままですね。」出村:「ライブラリー・リスト設定には、更新する物理ファイル(今回であれば社員マスタファイル)とILE RPGが入っているライブラリを選択する必要があります。今回はTSTAPIのみでOKですね。」
WEBサービスから受け取る情報について、設定の最終確認
出村:「今回もTSTAPIに保管されているILR RPGの情報のみで更新可能なので、こちらはデフォルトのままです。」
渡邊:「最終確認ですね。」
REST APIからデータベースのデータを追加・更新してみる
出村:「APIの登録ができたので、早速VS Codeを使用して既存のDBを更新しましょう。下記の画像は、これからリクエストを投げる段階の画面キャプチャです。」

・Send Requestを投げると...
出村:「【201 Created】とありますね。これで新規でデータが追加されたはずです。下記が、データ追加された際の画面キャプチャです。」



松田:「新規で【山田太郎】が追加されていますね。」
出村:「期待通り、新規でデータが追加されました。では、続いて、この社員番号5324番に対して、下記のような内容にデータを更新(書き換え)してみましょう。」

渡邊:「結果は【200 OK】ですね。データ更新の場合だと、新規追加とは違った応答が返ってくるのですね。」

松田:「無事に【山田太郎】から【田中花子】に更新できましたね。」

出村:「さて、ここまででデータの新規追加と既存データの更新(書き換え)を行いました。次は、デバッグを用いて本当にデータが受け取れているか検証していきましょう。」
REST APIをデバックする
出村:「RDiを開いてILE RPGのデバックをセットしましょう。RDiでのデバックは以前学びましたね。ILE RPGの実行はIWSサーバーのユーザIDが行っているので、サービスエントリーポイントを設定したらユーザIDを実行ユーザーに合わせましょう。第 5 回でIWSサーバのユーザIDを作成していますが、【IWSUSER】でしたね。ちなみに、復習ですがRDiのサービスエントリーポイントは、IBM i 上で特定ユーザーが特定プログラムを実行したときに、自動でRDiデバッガーを起動してデバッグできる仕組みのことです。詳しくは、第 4 回の記事を参照ください。」

渡邊:「設定できました。ブレークポイントは、どこに設定すれば良いでしょうか?」
出村:「今回は23行目に設定しましょう。ここはIWSから受け取った社員番号【REQ.syaibn】を【SYAIBN】に当てはめています。」

松田:「セットできました。今回のデバックでVS Codeでリクエストを送ることでILE RPGが実行されデバックが開始されるということで良いですか?」
出村:「その通りです。では、VS Codeからリクエストを送信してください。」
渡邊:「はい。それでは、先ほど更新で使ったリクエストをもう一度実行してみます。」

松田:「デバックが開始されましたね。ブレークポイントが設定してあるので、【再開】でブレークポイントまで進めます。」

渡邊:「ブレークポイントまで来ました。ステップオーバー(呼び出し先の処理をまとめて実行し、次の行に移る操作)で1行進めます。」

松田:「【SYAIBN】に5324が代入されていますね!」

出村:「そうです。RDiを利用すれば、デバッグを行う際に大きなメリットがあるんです。RDiでは、実行するプログラムと実行ユーザーを使ってデバックできますが、5250エミュレータから行う場合はとても大変です。5250エミュレータでは、まず最初にAPIリクエストを実行するジョブを特定しなければなりません。IWSサーバーのジョブは複数立ち上がっている可能性があり、STRSRVJOBコマンドでそのジョブを指定する必要があるんです。RDiの利用によって、VS Codeからリクエストした内容が、IWSを介して、ILE RPGに届いていることが確認できましたね。」
渡邊:「確かに、VS CodeからリクエストがIWSに投げられたタイミングでIWSサーバー側のジョブがわかるので、特定するのは大変ですね。」
出村:「その通りです。Web APIをデバッグするような時はRDiのサービスエントリーポイントの機能がとても役に立ちます。いろんな場面でRDiを活用していってほしいです。」
出村:「今回もIWSを使って、ILE RPGのWeb APIを作成しましたが、ILE RPG側ではJSON特有の内容を考慮はしておらず、JSONとパラメータの型をそろえたDS(データストラクチャ)を作るだけで、IWSがJSONの値をILE RPGのパラメータにセットしてくれている、さらに文字コードもユニコード(UTF-8)からEBCDICに変換されていることはとても重要です。」
松田:「そうですね。RPGに取り組んできた方にとっては、IWSを使うことで、Web APIのハードルがかなり下がることになりますね!」
出村:「その通りです。今回は、Web APIサーバの構築を行いましたが、より詳しい内容やWeb APIクライアントを学びたい方は、ベル・データの【BcoreAPI-HUB内製化支援パック】というサービスを活用ください。お客様にWeb APIの内製化を支援するサービスです。」
最後に
出村:「ここまで全8回にわたってRDi・Web APIの記事を発信してきましたが、いかがでしたか。」
松田:「正直、IBM i へのイメージががらっと変わった瞬間が多々あり、驚きの連続でした!私がインフラ部分をメインに扱ってきた人間だからかもしれませんが、IBM i にはまだまだ知られていない魅力があると感じました。中でも特に印象に残ったのは、前回から2回にわたって発信してきたWeb APIの技術でDBの更新ができることです。DBの更新といえば黒画面でDFU機能を使うことしか知らなかったのですが、Web APIからプログラムを用いて更新する術があったとは驚きでした。」
渡邊:「私はオープン系の技術を扱ってきたので、むしろ最終回になればなるほど慣れ親しんだキーワードが出てきた印象です。やはり、私にとってはRDiの技術が驚きでした。もちろん、条件はありますが、正直、今後の開発にRDiは手放せないと思います。」
出村:「お二人が感じたように本記事を読んでくださっている皆さんにも、気軽に試したい、そんな技術があったのかとIBM i を学ぶうえでの面白さを発見いただけたら嬉しいです。それでは、またいつかe-bellnetの枠を飛び越えて皆さんと技術交流ができることを期待しています。」
~ FIN ~

出村 宏志
ベル・データ株式会社 アプリケーションビジネス本部DX推進部
1995年ベル・データ㈱に入社
1999年より約15年ほどIBM i のインフラエンジニアを経験し、その後アプリケーション開発に従事。キャンプで焚火をしながらボーっとするのが最近の楽しみです。

渡邊 隆
ベル・データ株式会社 アプリケーションビジネス本部DX推進部
ネットワーク、オープン、セキュリティ、DX関連のプリセールス、構築、サポートを経て、現在はDX推進部に所属。工場DXソリューションを担当しながら、初挑戦のIBM i に格闘中。休日は、クラッシックピアノの練習や仲間との弾き合い会を楽しんでいます。

松田 三奈
ベル・データ株式会社 アプリケーションビジネス本部DX推進部
新卒よりインフラエンジニアとしてPowerサーバーのリプレイスに従事し、現在はDX推進部に所属。休日は、カフェ巡りや旅行など天候に関わらず外に出てアクティブに活動することが好きです。
あわせて読みたい記事

RPG開発者のためのIBM i モダナイゼーション入門!
RDi とWeb APIで新しい開発の世界を楽しもう - 第 1 回 -

RPG開発者のためのIBM i モダナイゼーション入門!
RDi とWeb APIで新しい開発の世界を楽しもう - 第 7 回 -

RPG開発者のためのIBM i モダナイゼーション入門!
RDi とWeb APIで新しい開発の世界を楽しもう - 第 8 回 -
