Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


RPGからWebAPIを利用する方法

近年、様々なサービスがWebAPIとして提供されています。
アプリケーション開発時には、外部の別アプリケーションと連携をとるために、WebAPIを使用することもよくあると思います。
一般的には、Java、PHP 、Python 、 Node.js 等サーバーサイドのプログラムでWebAPIを使用することが多いのですが、IBMiの進歩により、RPGプログラムからもWebAPIを利用できるようになっています。
Tipsでは、SYSTOOLSのHTTP関数を使用して、RPGプログラムからIBM CloudのWatson APIを呼び出し、結果取得する例をご紹介します。

SQLの SYSTOOLSのHTTP関数

IBMi DB2/400のSQLには、POSTやGET等のWebリクエストを送信する機能が追加されています。
SYSTOOLS に含まれているJAVAを使用したHTTP関数が用意されています。

◆(SYSTOOLS)HTTP関数の概要
https://www.ibm.com/docs/ja/i/7.5?topic=programming-http-functions-overview

SYSTOOLSを使用するには、「5770SS1 OPTION 33 PORTABLE APP SOLUTIONS ENVIRONMENT」がIBMiに導入されている必要があるため注意してください。

Tipsでは、RPGプログラムからWebAPIへアクセスする例として、IBM Cloud に含まれる、Watson APIの翻訳機能(Language Translator)を使用します。

 ※「IBMi V7R4 Tecnology Refresh PTF level 7」の環境で確認しています。

IBM Cloud とは

IBM Cloudは、IBMが提供するクラウドサービスで、クラウドサーバー環境の提供や、AIのWatson、ライブ動画配信等、様々なサービスが集約されたプラットフォームです。
無料使用枠も用意されているため、気軽に始めることができます。

◆IBM Cloud
https://www.ibm.com/jp-ja/cloud

Watson API

WatsonはIBMが開発した人工知能で、自然言語を処理して学習する機能を持っています。
学習した膨大のデータを用いて、人間の意思決定の支援を行うことができます。
そのような、Watsonの能力を活用できる、API(アプリケーションインターフェース)がIBM Cloudで公開されています。
Watson APIでは 自然言語の使用、翻訳、質問応答 感情分析、画像音声認識等、様々な機能が提供おり、無料使用枠内でもWatsonの機能を体験可能です。

IBM Cloudから Watson API リソース作成

Watson APIを使用するには、IBM Cloudのアカウントを作成します。
IBM Cloudアカウントの作成は以下のリンクを確認してください。

◆IBM Cloud アカウントのセットアップ
https://cloud.ibm.com/docs/account?topic=account-account-getting-started&locale=ja

アカウント作成後、IBM Cloudにログインしてください。

IBM Cloud画面

IBM Cloudのダッシュボード画面の「リソースの作成」から、IBM Cloudで使用することのできるリソースのカタログ一覧が表示されます。

IBM Cloud リソースのカタログ

Tipsの内容では、Watsonの翻訳機能を使用するため、カタログの中から、カテゴリー「AI/機械学習」を選択します。

Language Translator

「Language Translator」で翻訳機能を使用することができます。

Language Translator

各種設定を行い、作成してください。

リソースの情報

作成した項目には、左側メニューの「リソース・リスト」 > 「AI/機械学習」からアクセスできます。

資格情報、APIキーとURL

翻訳機能にアクセスするための、APIキーと、URLを取得してください。

RPGからの利用

HTML側

翻訳画面例

HTML側は、id属性TRANSの「翻訳」ボタンが押下された際に、アクションコード “A1″とid属性 SND01に入力されたテキストをRPGに送信して、結果をid属性RSL01に表示します。

動作例

入力のテキストエリアに、翻訳したい日本語を入力後、翻訳ボタンを押下すると、結果が右側のテキストエリアに表示されます。

SmartPad4i(Cobos4i)用ソースコードは以下リンクからダウンロードできます。
IBM Cloudのアカウントを作成後、APIのURL、APIキーを入手していただき、RPGプログラムの認証部分を書き換えることでお試しいただくことができます。
サンプルに含まれるreadme.txtを確認してサンプルを展開してください。

サンプルのダウンロード

RPG側

IBMi RPG側プログラムの注意点

RPGプログラムから、SYSTOOLSのHTTP関数を使用する場合には、SQLRPGLEを使用してプログラムを作成する必要があります。
また、ジョブのCCSIDが65535、5026環境では動作しないため、5035または1399のCCSIDを使用する必要があります。
QCCSID値が65535または、5026に設定されている環境では、プログラムのソースコードと、実行ジョブをCL等で明示的に5035に変更ください。

RPGプログラム例

H010  * <YOURCODE>
--->  * YOUR COMMENTS
     H  dftactgrp(*no)
H010  * </YOURCODE>
                             ~ 省略 ~
D030  * <YOURCODE>
     D SB0010          PR
D030  * </YOURCODE>
                             ~ 省略 ~
C050  * <YOURCODE>
--->  * CHECK ACTION CODE SPACTN HERE AND PROCESS.
--->  * YOUR CODE
     C     SPACTN        IFEQ      'F3'
     C                   GOTO      ENDPGM
     C                   ENDIF
     C     SPACTN        IFEQ      'A1'
      /free
                         SB0010();
      /end-free
     C                   GOTO      T200
     C                   ENDIF
C050  * </YOURCODE>
                             ~ 省略 ~
     *----------------------------------------------------------------
      * Watson API
      * SAMPLE
      *----------------------------------------------------------------
     p SB0010          b
     d                 pi
     D httpheader      s          10000a   varying
     D url             s           2048a   varying
     D response        s          10000a   varying
     D target          s           1000a   varying
     D paramData       s           1000a   varying
     D result          s           1000a   varying
     
      /free
          //リクエストを送信するURL
          url = '「IBM Cloudで入手したURL」';
          url = url + '/v3/translate?version=2018-05-01';
          //パラメータ
          target     =  %trim(ISND01);
          paramData  = '{"text": ["'+ target + '"], "model_id":"ja-en"}';
          // HTTPHEADER
          httpheader = '<httpHeader> ' +
            '<header name="accept" value="application/json" />' +
            '<header name="Content-Type" ' +
            ' value="application/json"/>' +
            '<header name="Authorization" value="Basic ' +
            '「BASE64エンコードしたAPIキー」' +
            '"/>' +
            ' </httpHeader>';
         // REQUEST
         EXEC SQL
           SELECT SYSTOOLS.HTTPPOSTCLOB(
              :url,
              :httpheader,
              CAST(:paramData  AS CLOB(1K) CCSID 1208))
              INTO :response
              FROM SYSIBM.SYSDUMMY1 ;
         if SQLCODE = *ZERO;
           EXEC SQL
             SELECT F1.RESULT INTO :result  FROM JSON_TABLE(:response
             ,'$' COLUMNS(
                    RESULT  VARCHAR(1000) PATH
                    '$.translations.translation'
                  )
                ERROR ON ERROR
             ) AS F1 ;
         endif;
         ORSL01 = %UPPER(result);
      /end-free
     p                 e

RPGプログラムはDesignerで配布されたプログラムを直接編集しています。外部プログラムとして定義していないため、H仕様書を追加するH010の箇所では、 dftactgrp(*no)を指定しています。

D030では、サブプロシージャ SB0010 としてAPI呼び出しの処理をまとめるため、D仕様書にプロトタイプ宣言を定義します。
C050では、ボタンが押下されてアクションコード(A1)をRPG側で受信した際に、サブプロシージャ SB0010を呼び出しています。

では、Watson APIを呼び出している、SB0010サブプロシージャについての説明になります。
「IBM Cloudで入手したURL」には、IBM Cloudの資格情報で取得した[URL]を設定します。
次に、Watson APIにアクセスするには認証をクリアする必要があります。
認証をRPGから送信するには、 httpヘッダーにAuthorizationを定義して
BASE64 でエンコードした apikey:「API Key」 を設定してください。

BASE64エンコード

BASE64エンコードは、Windows端末であれば、certutilコマンドを使用して行うことができます。
例えば、テキストファイルにapikey:「API Key」の情報を記入して、C:\BASE64\input.txt に保存してください。

BASE64エンコード certutilコマンド

コマンドプロンプトから、certutilコマンドを使用してBASE64エンコードできます。

certutil -f -encode 入力ファイル 出力ファイル

出力したファイルを開き、エンコードしたテキストを1行にして「BASE64エンコードしたAPIキー」へ設定してください。

入力ファイルがC:\BASE64\input.txt、出力ファイルをC:\BASE64\output.txtとする場合は、以下コマンドになります。

certutil -f -encode C:\BASE64\input.txt C:\BASE64\output.txt

翻訳APIのパラメータはJSON形式です。
翻訳する文字列と変換元と変換対象を設定して送信してください。
今回の例では、入力された文字を日本語(ja)から英語(en)に変換しています。

RPGプログラムの詳細

RPGプログラムからWebAPIを呼び出す方法として、SYSTOOLSのHTTPPOSTCLOBを使用しています。

◆HTTPPOSTBLOB および HTTPPOSTCLOB
https://www.ibm.com/docs/ja/db2-for-zos/12?topic=functions-httppostblob-httppostclob

HTTPPOSTCLOBは、HTTPのPOSTメソッドにより、指定したURLにリクエストを送信して結果をCLOBデータとして取得できます。

一つ目の引数にリクエストを送信するURL、二つ目の引数には httpheaderを指定します。
HTTPPOSTCLOBでは、httpheaderをXML形式で定義する必要があります。
<header name=”name” value=”value” />の形式でhttpheaderを定義します。
Watson APIで認証を受けるために、apiキーをhttpheaderで転送しています。

三つ目の引数は、リクエストボディ(request body)のデータです。
Watson APIに転送するデータはJSON形式で指定します。
textに翻訳対象の文字列、model_idに変換する対象と変換先の言語コードを指定します。
例えば、日本語から英語の場合は、”ja-en” となります。

HTTPPOSTCLOBの結果はがフィールドに返却されるため、into句を使用して値を取得します。
例えば、「本日は晴れです。」のテキストを翻訳した場合は、以下のような結果がresponseに格納されます。

{
  "translations" : [ {
    "translation" : "It's a fine day today."
  } ],
  "word_count" : 4,
  "character_count" : 8
}

次に、取得した結果をJSON_TABLEで解析をします。

◆JSON_TABLE の使用
https://www.ibm.com/docs/ja/i/7.4?topic=data-using-json-table

             SELECT F1.RESULT INTO :result  FROM JSON_TABLE(:response
             ,'$' COLUMNS(
                    RESULT  VARCHAR(1000) PATH
                    '$.translations.translation'
                  )
                ERROR ON ERROR
             ) AS F1 ;

$はjsonデータのルートを示し、ルートから > translations > translation のデータを取得するには上記のようになります。
ERROR ON ERROR はJsonデータを解析する際にエラーがあった場合に、SQLエラーを返すようにする記述です。

正しく解析できた場合、RESULTの列に結果が格納されるため、into句でresult変数に格納しています。
最後に、SP4iの出力フィールドORSL01 フィールドに値を格納すれば完了です。
なお、「Servlet Engine Administrator」 のCCSID設定が5026の場合は、%UPPERを使用して、大文字に変換するようにしてください。

おわりに

IBMiには様々な機能が追加されて日々進歩しています。
TipsではWatson APIにアクセスしましたが、その他 WebAPIでのアクセスにも是非ご活用ください。