HTTP_GET_VERBOSEを使用してURLをテストする
前回の記事、「SQLとRPGを使ったお遊びプログラム」では、HTTP_GET関数を使用して、 https://icanhazdadjoke.com/からウィットに富んだオヤジギャグを取得するお遊びプログラムを紹介しました。今回は、この素晴らしい関数のより実用的な使用例を紹介しようと思います。正確に言えば、HTTP_GETの別バージョン、HTTP_GET_VERBOSEですが、これも、DB2チームによってV7R3で導入されたものです。
極めてシンプルな実装ですが、以下のように、テストしたいURLをSQLステートメントの中に挿入することができます。
select *
from table(QSYS2.HTTP_GET_VERBOSE('https://icanhazdadjoke.com/',''))
後でRPGプログラムに組み込んで実行しますが、ひとまず、「SQLスクリプトの実行」でこのステートメントを実行してみましょう。結果として、2つの列が返されます。オヤジギャグが掲載されているHtmlが入ることになるRESPONSE_MESSAGE列と、RESPONSE_HTTP_HEADER列です。このヘッダーでは、HTTP_STATUS_CODEとContent-Typeという2つの部分に注目してください。
出だし上々ですが、私はHTMLよりJSONの方が好みなので、RESPONSE_MESSAGEがJSONとして返されるように、このステートメントを少し修正してみましょう。V7R4で、ヘッダー サポートが追加されました。これにより、text/htmlというデフォルトのアプリケーション タイプではなく、JSONとして返してもらいたいということを指定できるようになりました。
select *
from table(QSYS2.HTTP_GET_VERBOSE('https://icanhazdadjoke.com/',
'{"header": "Accept,application/json"}'));
良くなりました。これでRESPONSE_MESSAGEがJSONストリングとして返されるようになり、RESPONSE_HTTP_HEADER内のContent-Typeも、JSONを指定したことが反映されていることに注目してください。
この例では、1つのURLのみをチェックすればよかったわけではなく、URLが記されたファイルがありました。何千ものURLです。言うまでもなく、それらのURLを1つずつ上述のステートメントに差し込むとしたら、うんざりです。以下に示す次のバージョンでは、それらをファイルから取り出して、RESPONSE_HTTP_HEADERからHTTP_STATUS_CODEを分離します。RESPONSE_HTTP_HEADER内の最初の値が、HTTP_STATUS_CODEです。これにより、有効なURLを含んでいるレコードとそうでないレコードのリストをファイルから取得することが可能になります。
まず、以下のように、ファイルを作成して、2件のレコードを入力します。
CREATE OR REPLACE TABLE resource_listing (id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
resource CHAR(10), resource_url VarChar(255) Allocate(50));
Insert Into resource_listing (resource, resource_url)
Values ('DAD_JOKES','https://icanhazdadjoke.com/'),
('FAV_JOKES','https://icanhazdadjoke.com/favorite/');
Select * From resource_listing;
うまくできました。ここで、テスト データがあります。「200(成功)」を返すことになるレコードと、「404(失敗)」を返すことになるレコードです。
これで、上述のSQLを変更して、テスト ファイル内のすべてのURLをチェックすることができます。共通表式(CTE)は、メリットが多いので、私は大好きですが、私にとって何よりのメリットは、読みやすいことと系統化されることです。そのため、SQLステートメントの以下のバージョンでは、テストするにふさわしいresourceおよびresource_urlsのリストを収集するだけのCTEから始めました。
With resource_urls as (Select resource, resource_url
From resource_listing
Where Trim(resource_url) <> '')
Select resource, resource_url, HTTP_STATUS_CODE
From resource_urls,
table(QSYS2.HTTP_GET_VERBOSE(resource_url)),
json_table(RESPONSE_HTTP_HEADER, 'lax $' columns
(HTTP_STATUS_CODE num(3) path '$.HTTP_STATUS_CODE'))
上述のSQLステートメントの2つ目の部分では、RESPONSE_HTTP_HEADERからHTTP_STATUS_CODEが引き離されます。これで、SQLの結果として、リソースと、適切なURLかどうかを示す簡潔なリストが返されます。
そして、もちろん、SQLステートメントに単純なWhere節を追加することによって、注目する必要があるURLを分離することができます。
上述したSQLをビューとして作成すれば、きれいな仕上げとなるでしょう。RPGプログラムにSQLを組み込むときは、コードをすっきりさせておきたいので、私はたいてい、ビューから select * するようにしています。しかし、HTTP_GETおよびHTTP_GET_VERBOSE関数をどのように実装するにしても、上述した例が有用だと思っていただけたとしたら幸いです。