2025年1月22日水曜日

Oracle APEX 24.2のRESTデータ・ソースのトークンによるページネーションのサポートを確認する

Oracle APEX 24.2のRESTデータ・ソースで新たに、ページ・サイズとページ・トークンによるページネーションがサポートされました。以前に記事「東京都のオープンデータAPIを呼び出してデータを取得する」で、PL/SQLを使って東京都が提供しているオープンデータAPIを呼び出す方法を紹介していますが、APEX 24.2からはPL/SQLのコーディングは必要なく、RESTデータ・ソースの設定だけでページネーションに対応できます。

以下より、東京都のオープンデータAPIを呼び出して文化財一覧のデータを取得し、Oracle APEXでレポートなどを表示するアプリケーションを作成してみます。

作成したAPEXアプリケーションは、以下のように動作します。


今回使用するAPIは、東京都の以下のページで紹介されています。

オープンデータAPIについて

この中のCulturalPropertyを呼び出します。

以下より、アプリケーションの作成手順を紹介します。

最初に空のAPEXアプリケーションを作成します。名前Tokyo Metropolitan Government Open Data APIとします。


アプリケーションが作成されたら、共有コンポーネントRESTデータ・ソースを開きます。


作成済みのRESTデータ・ソースが一覧されます。作成をクリックします。


RESTデータ・ソースの作成はデフォルトの最初からのまま変更せず、へ進みます。


東京都のオープンデータAPIのエンドポイントを設定します。

RESTデータ・ソース・タイプ簡易HTTPです。名前Tokyo Cultural Propertiesとします。URLエンドポイントの指定は以下になります。

https://api.data.metro.tokyo.lg.jp/v1/CulturalProperty

へ進みます。


リモート・サーバーの設定に移ります。リモート・サーバーが未設定の場合は- 新規作成 -となります。自動的に検出されたベースURLサービスURLパスは、通常は変更不要です。

へ進みます。


東京都のオープンデータAPIのページネーションの仕組みを設定します。

東京都のオープンデータAPIは、以下の形式でレスポンスを返します。
[
    [
         { 文化財1のJSONデータ },
         { 文化財2のJSONデータ },
         ....
         { 文化財NのJSONデータ }
    ],
    {
         "endCursor": "後続のAPI呼び出しの引数cursorに与える値",
         "moreResults": "MORE_RESULTS_AFTER_LIMIT",
         ...
     }
]
よって、ページネーションとして以下の設定を行います。

ページ区切りタイプとしてページ・サイズとページ・トークンを選択します。APIの仕様よりページ・サイズURLパラメータlimitページ・サイズ最大100を設定します。設定可能な仕様上の最大値は1000です。

ページ・トークンURLパラメータcursor次のページ・トークン・セレクタ[1].endCursorです。REST APIのレスポンスよりセレクタ$[1].endCursor(内部で指定したセレクタの先頭に$を付けます)で取り出した値が、続けて発行されるREST APIの引数cursorに割り当てられます。

東京都のオープンデータAPIの仕様では、moreResultsの値がMORE_RESULTS_AFTER_LIMITであれば追加のデータが存在し、moreResultsNO_MORE_RESULTSであれば、データの終了となっています。

この仕様に合わせて、その他の行セレクタとして[1].moreResultsを指定し、次の値のときのその他の行次と等しいその他の行属性値としてmore_results_after_limitを設定します。その他の行属性値は英小文字で記述します。現在は、大文字小文字を区別せずに一致を確認するために、取り出した文字列を一律で小文字に変換しその他の行属性値に指定した値と比較しています。そのため、その他の行属性値を小文字で指定する必要があります。製品の不具合として、将来の修正対象となっています。

ページ区切りタイプページ・サイズとページ・トークンである場合、その仕組みより順方向のページングのみが可能です。ページ番号またはフェッチ・オフセットが引数として与えられないため、中間のデータだけが欲しい場合でも、つねにデータの先頭から順番に読み出す必要があります。そのため、多数のREST APIを発行し、何度も同じデータを取得することが起こり得ます。

この点については、Oracle APEXのRESTデータ・ソースの同期化を構成して、ローカル・データベースに取得したデータを保存することで対応することにします。

へ進みます。


認証は不要なのでオフのままにします。そのまま検出をクリックします。


東京都のオープンデータAPIが呼び出され、文化財一覧のデータが取得されます。しかし、表示は1行だけで、UpdatedやRevisionといった、文化財とは関係ないデータが表示されます。これは、東京都のオープンデータAPIが配列の2番目の要素として返している、REST APIリクエストのメタデータです。

レスポンス本文を開くと、実際に受信されたデータを確認できます。


受信したデータを確認したのち、データ・プロファイルを開き、不要な属性を削除します。


検出された属性のうち、セレクタ@typeを含む属性はOracle APEXで扱うことはありません。また、REST APIのメタデータに関する属性も不要です。

以下の名前の属性を削除します。

C_TYPE, 参照__TYPE, 名称__TYPE, UPDATED, REVISION, ENDCURSOR, EX_員数__TYPE, 管理者__TYPE, 管理者_種別コード__TYPE, MORERESULTS, 権利管理__TYPE, 設置地点__TYPE, 設置地点_住所__TYPE, 設置地点_連絡先__TYPE, 設置地点_地理座標__TYPE, 設置地点_利用可能時間__TYPE, メタデータ__TYPE, メタデータ_作成者__TYPE, EX_文化財指定日__TYPE




検出された52の属性から19の属性を削除し、結果として33個の属性を持ったRESTデータ・ソースを作成します。

RESTデータ・ソースの作成をクリックします。


RESTデータ・ソースTokyo Cultural Propertiesが作成されます。RESTソース名をクリックし、作成されたRESTデータ・ソースをさらに調整します。


データ・プロファイルの編集をクリックします。


IDEX_員数_数値設置地点_地理座標_経度設置地点_地理座標_緯度メタデータ_作成者_IDデータ型数値になっています。実際には数値としては扱えないデータが含まれていることがあります。そのため、数値のままだとエラーが発生します。


エラーの発生を回避するため、これらの列のデータ型をすべてVarchar2に変更します。長さ4000とします。数値として扱う場合は、APEXのアプリケーション側でto_numberを呼び出して数値に変換します。


IDは本来主キーとして設定できるはずなのですが、APIのレスポンスに空行が含まれているため、列IDの主キーをオンにするとエラーが発生します。そのため、主キー設定も行いません。

設定行セレクタ[0]を設定します。REST APIのレスポンスとして受信したJSON配列の最初の要素(インデックスとしては0)がデータで、次の要素(インデックスとしては1)はレスポンスのメタデータであるため、最初の要素だけをデータとして限定します。

データ・プロファイルに以上の変更を実施し、変更の適用をクリックします。


リクエストの発行を節約するためにRESTデータ・ソースの同期化を使い、ローカル・データベースに文化財一覧の情報をキャッシュします。

RESTデータ・ソース同期化の管理を開きます。


同期先として新規表を選択し、表名EBAJ_TOKYO_CULTURAL_PROPERTIESを指定します。RESTデータ・ソースの同期化が完了すると、文化財の情報を表EBAJ_TOKYO_CULTURAL_PROPERTIESから参照できるようになります。

保存をクリックします。


REST同期化の設定画面が開きます。

同期化表が存在しません。とレポートされています。SQLの表示をクリックし、表EBAJ_TOKYO_CULTURAL_PROPERTIESを作成するDDLを確認します。


以下の列名が長すぎて、途中で名前が切れてしまっています。また、列名と型名が繋がっている部分もあります。

   ,"設置地点_利用可能時間_終了 VARCHAR2(4000)
   ,"設置地点_利用可能時間_開催 VARCHAR2(4000)
   ,"設置地点_利用可能時間_開始 VARCHAR2(4000)

そのため、この画面からは表を作成することができません。


SQLワークショップSQLコマンドを開き、エラーが発生しないように修正した以下のDDLを実行します。



アプリケーション・ビルダーに戻り、RESTデータ・ソース同期化の管理を開きます。同期化表EBAJ_TOKYO_CULTURAL_PROPERTIESが作成されているため、表のステータスとして「表"EBAJ_TOKYO_CULTURAL_PROPERTIES"は同期化の準備ができています」と表示されます。

初回の同期化では、同期タイプ追加または置換を選択します。データ・プロファイルに主キーが含まれていないため、マージはできません。次回以降は置換を選択します。

保存して実行をクリックすると、作成したRESTデータ・ソースを使って東京都の文化財一覧を読み出し、表EBAJ_TOKYO_CULTURAL_PROPERTIESに保存します。

RESTデータ・ソース最後の同期化ログの情報より、REST同期化が成功したことを確認します。

ログから表EBAJ_TOKYO_CULTURAL_PROPERTIESに248行の文化財のデータが読み込まれたことが確認できます。RESTデータ・ソースのページネーションの設定ではlimitに100を設定しているため、3回のリクエストですべてのデータを読み取っています。


以上でRESTデータ・ソースの作成が完了し、データもローカル・データベースにキャッシュされました。

これから、アプリケーションにページを追加していきます。

最初に対話モード・レポートのページを追加します。

ページの作成をクリックします。


対話モード・レポートを選択します。


ページの名前文化財一覧とします。データ・ソースとしてRESTソースを選択し、RESTデータ・ソースとしてTokyo Cultural Propertiesを選択します。

ページの作成をクリックします。


対話モード・レポートを含むページが作成されます。

ページ作成直後は、対話モード・レポートは同期化表を参照する設定になっていません。対話モード・レポートのリージョンを選択し、REST同期化ローカル表の使用オンにします。


以上でページを実行します。

対話モード・レポートに東京都の文化財一覧が表示されます。東京都のオープンデータAPIを呼び出して取得されたデータがそのまま表示されているため、見にくい部分もあります。


オープンデータAPIから得られたデータを加工するビューEBAJ_TOKYO_CULTURAL_PROPS_Vを作成します。これから作成するファセット検索とマップのソースとして使用します。


作成したビューをソースとしたファセット検索のページを作成します。

ページの作成を実行し、ファセット検索を選択します。

ページの名前文化財検索データ・ソース表/ビューの名前としてEBAJ_TOKYO_CULTURAL_PROPS_Vを選択します。

へ進みます。


ファセットとして列TYPE(東京都の文化財一覧としては種別に当たるデータ)を選択したいのですが、これはJSON配列であるためタイプがclobとして認識されています。そのため、ファセットとして選択できません。

表示形式レポートを選択し、ファセットとしては何も選択しません。ページの作成後に列TYPEをファセットとして追加します。

以上でページの作成をクリックします。


ページが作成されたら、レンダリング・ツリーのファセット上でコンテキスト・メニューを表示し、ファセットの作成を実行します。


作成したファセットの識別名前P3_TYPEとします。タイプチェック・ボックス・グループです。

ラベルは本来の名前である種別LOVタイプ個別値を選択します。アクション・メニューフィルタチャートは不要なのでオフとします。ソースデータベース列はTYPEデータ型VARCHAR2です。複数の値タイプJSON配列を選択し、フィルタの結合AND(論理積)を選択します。

ページを作成するウィザードでは列TYPEの型がClobと認識されていましたが、実際にはVARCHAR2です。また、複数の値タイプJSON配列を選択するにはVARCHAR2である必要があります。


検索結果のレポートに含まれる列LONおよびLATはそれぞれ経度と緯度の数値で、列TYPEはファセットとして使用しているため、レポートに表示する必要はありません。

LON、LATおよびTYPEを選択し、タイプ非表示に変更します。


以上でファセット検索のページは完成です。ページの保存と実行を行い、動作を確認します。


最後に、地図上に文化財の位置を表示するページを作成します。

ページの作成を実行し、マップを選択します。

ページの名前文化財の場所データ・ソース表/ビューの名前としてEBAJ_TOKYO_CULTURAL_PROPS_Vを選択します。

へ進みます。


 マップ・スタイルとしてポイントを選択します。

マップ属性ジオメトリ列タイプとして2つの数値列を選択し、経度列LON(Number)緯度列LAT(Number)とします。ツールチップ列NAME(Varchar2)を選択します。

ファセット検索ページの作成オンにします。

以上でページの作成をクリックします。



マップを含んだページが作成されます。

最初に先ほど作成した文化財検索のページと同様に、種別のファセットを作成します。

レンダリング・ツリーのファセット上でコンテキスト・メニューを表示し、ファセットの同期を実行します。

ファセットの同期ではなくファセットの作成を実行して作成したファセットは、なぜかマップ・リージョンと連動しませんでした。ファセットの同期であればマップ・リージョンと連動するファセットが作成されるため、こちらの実行をお勧めします。


ビューEBAJ_TOKYO_CULTURAL_PROPS_Vに含まれるすべての列がファセットとして追加されます。ファセットP4_SEARCHP4_TYPEを除き、その他のファセットを削除します。


 ファセットP4_TYPEは、文化財検索のファセットP3_TYPE同じ設定にします。


マップの表示を少し調整します。レイヤー文化財の場所を選択します。

行のマッピング主キー列としてIDを選択します。

ツールチップ拡張フォーマットオンにし、HTML式に以下を記述します。ツールチップに文化財の名前を太字、その下に住所を表示します。

<b>&NAME.</b>
<br>
&ADDRESS.

 情報ウィンドウタイトル列NAME本体列DESCRIPTIONを指定します。

 ファセット検索が付いた文化財の場所を表示する地図のページが作成できました。

以上で、東京都が提供しているオープンデータAPIを活用したAPEXアプリケーションは完成です。

Oracle APEX 24.2のRESTデータ・ソースの新機能としてトークンによるページネーションがサポートされたため、ほぼノーコードでアプリケーションを作成することができました。

さて、Oracle Databaseに東京都が提供しているオープンデータが保存されています。

以前の記事「Oracle Databaseに接続するMCPサーバーを作成しClaudeから問い合わせる」で紹介しているClaudeのデスクトップ・アプリケーションに組み込んだMCPサーバーからオープンデータを保存しているスキーマに接続することにより、AIによる問い合わせも可能です。

 Claude 3.5 Sonnetに、作成した表EBAJ_TOKYO_CULTURAL_PROPERTIESを認識させてから、東京の名勝を一覧してもらいました。10件の名勝が一覧されました。


ファセット検索でも、東京都の文化財として登録されている名勝は10件でした。


今回の記事は以上になります。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/rest-token-pagination-with-tokyo-opendata.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。