近年、様々なサービスが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で使用することのできるリソースのカタログ一覧が表示されます。
Tipsの内容では、Watsonの翻訳機能を使用するため、カタログの中から、カテゴリー「AI/機械学習」を選択します。
「Language Translator」で翻訳機能を使用することができます。
各種設定を行い、作成してください。
作成した項目には、左側メニューの「リソース・リスト」 > 「AI/機械学習」からアクセスできます。
翻訳機能にアクセスするための、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 に保存してください。
コマンドプロンプトから、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でのアクセスにも是非ご活用ください。