メニューボタン
IBMi海外記事2024.06.12

RPG開発者向けのWebの基本概念、パート1

Chris Ringer 著

1990年代には、RPG III F仕様書のみでデータにアクセスしていたことが思い起こされます。しかし、今日では、そうした重要なデータの一部は、クラウドにあるかもしれません。喜ばしいことに、IBM i からそうしたリモート データにアクセスするには、 HTTPAPI および RXS といったツールや、 SQL HTTP のようなSQL関数を利用できます。しかし、そうしたHTTPリクエストで構成要素を実際にどのようにフォーマットしたらよいかについては、あまりよく知られていないかもしれません。

この記事では、Webに送信する前に、HTTPリクエストでそれらの構成要素を構築するためのいくつかの手法について見て行こうと思います。

HTTP GetおよびPost

HTTPリクエストで最もよく使用される2つのメソッドは、GETとPOSTです。GETは、Webサーバーからリソースを取得するのに使用します。普段、ブラウザのアドレス バーにURLを入力するときには、GETを実行していることになります。POSTについては、データを更新する可能性がある、入力フィールドおよび送信ボタンがあるフォームを思い浮かべてみたら、分かりやすいかもしれません。では、それぞれのメソッドのフォーマットについて確認してみましょう。

GETの例

01 GET /usa/getWeather?zip=46256&type=hourly HTTP/1.1
02 Host: myCoolWeather.com
03 User-Agent: MyClientTool/1.0 (System Test/7.5)

01行:GETは、静的Webページ、画像、またはWeb API(プログラム)などのようなリソースを要求します。

/usa/getWeatherは、Webサーバー上のリソースのパスおよび名前です。オプションで、URLのWebページ名に続けて、キーと値のペアでデータの照会ストリングを指定することもできます。その場合、Webサーバーは、その照会ストリングに基づいて、レスポンスで結果をフィルタリングすることもあります。URLの最大長は、照会ストリングを含めて、Chromeで約2000文字であるため、それを超えないようにします。そして、HTTP/1.1は、クライアントがサポートするHTTPのバージョンです。IBM i で言えば、v7.4やv7.5というようなものです。HTTP/1.1は古めのバージョンですが、定期的にアップデートされており、今日でもまだ幅広く使用されています。

02行:Hostは、/usa/getWeatherページが格納されているWebサーバーです。

03行:User-Agentは、ブラウザ名とバージョンおよびデバイスといった、リクエストを送信するクライアント(エージェント)についての情報です。これは実際にはどのようなプレーン テキストでも構いませんが、一部には、ブラウザおよびスマートフォン用に、User-Agentに組み込まれている情報もあります。

POSTの例

01 POST /post HTTP/1.1
02 Host: httpbin.org
03 Authorization: Basic RGFubnlOb29uYW46R29sZmVy
04 Content-Type: text/plain
05 Content-Length: 4
06
07 ibm!

01行:POSTは、リクエストのボディでデータが渡されることを意味します(07行を参照)。/postは、Webサーバー上のWeb API(プログラム)のパスおよび名前です。繰り返しになりますが、HTTP/1.1は、クライアントがサポートするHTTPのバージョンです。

02 - 05行:これらの行は、リクエストのヘッダー(メタデータ)であり、サーバーは、どのようなデータを受け取るのか、レスポンスをどのようにフォーマットしたらよいかを認識します。

02行:Hostは、/post Web APIが格納されているWebサーバーです。

03行:Authorizationヘッダーには、認証情報またはアクセス トークンが格納されます(Web APIによって要求される場合)。

この例では、認証情報はBase64としてエンコードされます(詳細は後述します)。

04行:ここでは、ボディのデータは、プレーン テキストだけです。RPGで言えば、変数を、varchar、integer、データ構造などとして宣言するようなものです。

05行:リクエスト ボディのデータの長さは、4バイトです。ボディから4バイトを読み込んだ後に、Webサーバーはレスポンスを生成することができます。

06行:空白行は、ヘッダーが終わり、次はデータであることを意味します。どんなデータが来るのかワクワクします。

07行:このPOSTのボディは「 ibm! 」で、長さは4バイトです。ボディの最大長は、数メガバイトになる場合もあり、上限はWebサーバーの構成によって制御されます。

リクエストのWeb API の仕様によって、GETまたはPOST(あるいは PUT または DELETE)が必要かどうかが判定されます。

Base64スキーム

Web APIは、通常、画像やデジタル署名のようなバイナリー データではなく、テキスト データを受け取るように設計されています。 Base64 スキームは、一連のビットが、64種類のプレーン テキスト文字(+ / 0-9 a-z A-Z)にエンコードされることを可能にします。そして、+ および / は、URLにおける予約文字であるため、それぞれダッシュ(-)およびアンダースコア(_)が代わりに使用されることがあります。Base64でエンコードされたデータは、GETの照会ストリングおよびPOSTのボディの両方で使用される場合があります。

ストリングまたはファイルがBase64にエンコードされる際には、一連のビットは、セクステット(6ビット バイト)ごとに切り分けられ、それぞれがBase64の64文字にマッピングされます(図1)。3バイトごとに4バイトへ拡がることに注意してください。

図1

長さが4で割り切れる数になるように、最後のBase64ストリングには、末尾に1つまたは2つの等号がパディング(埋め込み)されることがあります(図2)。Web APIによって、こうしたパディングを必要とするものと、しないものがあります。

図2

以下は、EBCDICストリングをBase64へ変換するためのコード スニペットです。覚えておくべき極めて重要なことは、Base64 ASCIIで終わるようにするためには、EBCDICではなく、ASCIIストリングで始める必要があるということです。また、切り捨てられないようにするために、「TO(変換先)」の変数のサイズを、「FROM(変換元)」の変数に比べて35%大きくしています。

01 dcl-s wkString        varChar(1000);
02 dcl-s wkStringAscii   varChar(1000) ccsid(*UTF8);
03 dcl-s wkStringAscii64 varChar(1350) ccsid(*UTF8);
04 dcl-s wkString64      varChar(1350);
05 wkString = 'ibm';
06 wkStringAscii = wkString;
07 exec sql set :wkStringAscii64 = BASE64_ENCODE(:wkStringAscii);
08 wkString64 = wkStringAscii64;  // aWJt

01行および04行:これらの行は、EBCDIC変数です。

02行 - 03行:これらの行はUTF-8変数(CCSID 1208)ですが、簡潔にするために、ASCIIと呼ぶこととしましょう。

05行:変数を「ibm」に設定します。

06行:EBCDICストリングをASCIIに変換します。

07行:SQL関数、 BASE64_ENCODE によって、ストリングがBase64へ変換されます。

08行:ASCIIストリングをEBCDICに変換します。

URLエンコード

URL における一部の文字(& : . = + $ , / ? % # など)は、特別な意味を持つ予約文字です。照会ストリングでこれらの文字をデータとして表現するには、16進数字にパーセント エンコーディングする必要があります。RPGで言えば、単一の引用符リテラルは、ストリングに埋め込まれるときには、引用符2つにする必要があるというようなものです。

bookOwner = 'Bob''s book';

ここでは、SQL関数、 URL_ENCODE を使用して、URLで問題なく使用されるようにストリングを変換します。

01 dcl-s wkString     varChar(1000);
02 dcl-s wkStringURL  varChar(3000);
03 wkString = 'start :/?& middle =#+ end';
04 exec sql values(URL_ENCODE(:wkString)) into :wkStringURL;
05 exec sql values(replace(URL_ENCODE(:wkString),'+','%20')) 
06 into :wkStringURL;

01行 - 02行:2つ目の変数のサイズが、1つ目の変数の3倍であることに注目してください。URLエンコードされたストリングは、元の値から、200%以上大きくなる場合もあります(図3)。

03行:ストリングにいくつか予約文字を追加しました。

04行:URL_ENCODE関数によって、ストリングがエンコードされます。

start+%3A%2F%3F%26+middle+%3D%23%2B+end

行05 - 行06: 行04のURLストリング内の4つのプラス記号に注目してください。URLの照会ストリングでは、スペースはプラス記号または「%20」としてエンコードされる場合があります。利用しているWeb APIによっては、どちらかが優先される場合があるかもしれません。不確かな場合は、SQL関数、 REPLACE を使用して、「+」をすべて「%20」へ変換します。

start%20%3A%2F%3F%26%20middle%20%3D%23%2B%20end

図3

どのHTTPヘッダーが必要とされるか、データがリクエストでどのようにフォーマットされる必要があるかは、結局のところ、利用する必要があるWeb APIの技術仕様によって決まります。この記事のコード スニペットを試してみたい場合は、コードをRDiエディターへコピーすることができますが、もちろん、行番号は問題です。コマンドLLT2およびLLTでコードのブロックを区切ることによって、すぐにそれらを除去することができます(図4)。これにより、行が2文字分、左へ移動し、行番号がトリミングされます。

図4

今回は、ここまでとします。「パート2」をお楽しみに。楽しいコーディングを。

あわせて読みたい記事

PAGE TOP