SELECT 実行
SELECT クエリが発行されると、本製品 は、スキーマのGET メソッドを実行します。GET メソッドは、本製品 の組み込みオペレーションを呼び出しREST を処理します。 GET メソッドを呼び出すことで、データのリクエストを制御できます。
以下の手順は、データのリクエストに対して制御を加えるいくつかの方法を示しています。
- SELECT WHERE を使用して、リモートサーバー側のデータを検索
- LIMIT を使用して、サーバーから返される結果を制限
- ページングを実装
クエリ処理
デフォルトで、本製品 は、クライアント側でクエリを処理します。ローカルでSELECT ステートメントを実行するために必要な設定は、XPath およびURI 接続プロパティだけです。
(本製品 は、その他のクエリをクライアント側で処理する間に、サポートされているクエリをサーバーにオフロードすることもできます。 これらのフィルタをサーバーにプッシュすると、LIMIT、JOIN、GROUP BY、ORDER BY といったクエリの後半の段階を最適化できます。)
REST へのSelect の実行
以下の手順で、クライアント側で処理されたSQL-92 クエリを実行できるスクリプトを構築する方法を説明します。 データ処理操作を呼び出す前に、URI、およびオプションでXPath を指定する必要があります。 api:set キーワードを使って、これらの属性を宣言します。
-
URI 属性を、ローカルファイルまたはHTTP アクセス可能なアドレスに設定します。
<api:set attr="uri" value="NorthwindOData.xml" />
-
必要であれば、XPath 属性を、個々の行を構成するデータのXPath に設定します。 デフォルトでは、本製品 はドキュメントをスキャンして行を検出します(階層データの解析 を参照)。
<api:set attr="XPath" value="/feed/entry/" />
-
GET メソッドで処理を呼び出します。スクリプトブロック内でapi:push キーワードを使用して処理を呼び出します。op パラメータを使って処理を指定します。このキーワードは、処理の結果をスキーマの出力にプッシュします。
<api:script method="GET"> <api:set attr="method" value="GET"/> <api:set attr="uri" value="[uri]?$format=atom"/> <api:call op="xmlproviderGet"> <api:push /> </api:call> </api:script>
サーバー上でSELECT WHERE を処理
このセクションでは、SELECT WHERE ステートメントをREST API に対する検索リクエストに変換する方法を示します。
プロシージャは次のステートメントを使用します。
SELECT * FROM <table> WHERE modifedAt < '2017-10-10' AND modifedAt > '2017-09-01'
サーバーがクエリパラメータを介してこのフィルタをサポートする場合は、api:info カラム定義のother:filter プロパティを使用して、希望するマッピングを指定できます。 上記のクエリでは、このプロパティを使用して、modifiedAt < '<date>' フィルタを特定の日付より前に修正された結果を返すクエリパラメータにマッピングし、modifedAt > '<date> フィルタを、その日付以降に修正された結果をフィルタリングするクエリパラメータに使用できます。
other:filter はセミコロン区切りリストで、フォーマットは以下のとおりです:<parameter name>:<operator list>
- <parameter name> はクエリパラメータの名前
- <operator list> はマッピングに使用される演算子のカンマ区切りのリスト
有効な演算子は<、<=、=、>、>=、およびLIKE です。
このマッピングを実行するには、modifedAt カラム定義に次のマークアップを使用します:
<attr name="modifiedAt" xs:type="datetime" readonly="false" other:xPath="content/properties/modifiedAt" other:filter="modifiedBefore:<;modifiedSince:>" />
このクエリは次のリクエストになります:
[url]?modifedBefore=2017-10-10&modifedSince=2017-09-01
API フィルタがクエリパラメータで渡されない場合は、スクリプトで渡す必要があります。
例えば、/persons/{name}/data endpoint をクエリして名前でフィルタするAPI を考えてみましょう。
SELECT * FROM Persons WHERE (Name = 'Fran Wilson')
スキーマのGET メソッドでは、Items in API Script のいずれかの_input アイテムの属性を使用して検索条件にアクセスし、HTTP データ取得要求を作成します。 対応する以下のスクリプトはリクエストを作成します。
api:check 要素は、その値にアクセスを試みる前に、属性の有無をチェックするのに便利です。さまざまなValue Formatters を使用して、URL エンコードのような変換を行うことができます。
<api:script method="GET">
<api:check attr="_input.Name">
<api:set attr="uri" value="[uri]/[_input.name|urlencode]/data"/>
</api:check>
</api:script>
疑似カラムによる検索
結果に戻されたカラム以外の入力を使用して検索条件を作成したい場合、WHERE 句に疑似カラムを指定できます。
例えば、Weather Underground API は、指定された場所の予測を返すことをサポートしています。
Location 自体は予測データの一部ではなく、以下のリクエストのようにリクエストURI に指定されます。
http://api.wunderground.com/api/{MyAPIKey}/hourly/q/{MyLocation}.xml
例えば、次のSQL クエリは、zip code 27516のフォーキャストを取得します。
SELECT * FROM Hourly WHERE Location="27516"
上記のクエリを実装するために、以下のようにLocation 疑似カラムを追加します。
- ロケーション入力パラメータをapi:info ブロックのカラム定義に追加します。
(Location は必須です。指定されていない場合、本製品 はエラーを返します。)
<api:info> ... <input name="Location" required="true"/> </api:info>
- URI を構築するには、_input アイテムのLocation 属性を参照します。
<api:set attr='uri' value="http://api.wunderground.com/api/[_connection.APIKey]/hourly/q/[_input.Location].xml"/>
- リクエストを行いレスポンスを処理するには、処理を呼び出します。
<api:script method="GET" > <api:push op="xmlproviderGet"/> </api:script>
ページングの実装
自動ページングをサポートするには、Rows@Next 入力をapi:info ブロックのカラムリストに追加します。
<input name="rows@next" desc="Identifier for the next page of results. Do not set this value manually." />
これをattr パラメータではなくinput パラメータにすると、
カラムリストに情報が表示されなくなります。ドライバーの内部ページングメカニズムを無効にするには、EnablePaging 属性をFALSE に設定する必要があります。
<api:set attr="EnablePaging" value="TRUE" />
ドライバーは以下の4種類のページング実装を自動的にサポートします。
- 次のページのURL がレスポンスに返される場合
- クエリに現在のページオフセットを指定するパラメータが含まれる場合
- 次のリクエストのクエリパラメータにページトークンを送信する場合
- クエリに現在のページ番号を指定するパラメータが含まれる場合
これらの実装について、以下のセクションで説明します。
次ページのURL によるページング
サービスが次のページのURL をレスポンスボディやヘッダに返すときは、'pageurlpath' 属性をこのデータの場所に設定します。 この場所に値が存在する場合は、次のリクエストのURL を設定するために使用されます。
次ページのURL がレスポンスボディに渡される場合は、'pageurlpath' をエレメントのXPath に設定します。
<api:set attr="pageurlpath" value="/data/nextPage" />
次ページのURL が'Link' ヘッダとともにレスポンスヘッダに渡される場合は、'pageurlpath' の前にheader: を付けてその場所を示すことができます。
<api:set attr="pageurlpath" value="header:Link" />
レコードオフセットによるページング
サービスがページングを制御するレコードオフセットクエリパラメータを提供する場合は、オフセットクエリパラメータの名前、ページサイズクエリパラメータの名前、および渡されるページサイズを設定できます。
これを制御するパラメータがない場合は、ページサイズパラメータを設定する必要はありません。ただし、その場合はpagesize をデフォルトのページサイズに設定する必要があります。
<api:set attr="pageoffsetparam" value="offset" />
<api:set attr="pagesizeparam" value="limit" />
<api:set attr="pagesize" value="100" />
pageoffsetparam とpagenumberparam には、開始ページを指定することもできます。次に例を示します。
<api:set attr="pageoffsetparam" value="offset" />
次のようになります。
URI?offset=0<OtherParams>
オフセット値を1に設定します。
<api:set attr="pageoffsetparam" value="offset;1" />
次のようになります。
URI?offset=1<OtherParams>
ページ番号によるページング
レコードオフセットと同様に、サービスがページ番号を設定するクエリパラメータを提供する場合は、ページ番号クエリパラメータの名前、ページサイズクエリパラメータの名前、および渡されるページサイズを設定できます。
これを制御するパラメータがない場合は、ページサイズパラメータを設定する必要はありません。ただし、その場合はpagesize をデフォルトのページサイズに設定する必要があります。
<api:set attr="pagenumberparam" value="page" />
<api:set attr="pagesizeparam" value="pagesize" />
<api:set attr="pagesize" value="100" />
トークンによるページング
レスポンスボディにトークンが返される場合、トークンは'pagetokenparam' および'pagetokenpath' 属性を介して、後続リクエストでページングパラメータに渡される必要があります。 'pagetokenpath' はエレメントのXPath に設定する必要があります。
他のページがあるかどうかを示す変数を送信するサービスもあります。その場合は、'hasmorepath' 属性をXPath に設定することもできます。
ページトークンがクエリパラメータで渡される場合は、'pagetokenparam' をパラメータの名前に設定します。
<api:set attr="pagetokenpath" value="/data/token" />
<api:set attr="hasmorepath" value="/data/has_more" />
<api:set attr="pagetokenparam" value="nextpagetoken" />
has_more がtrue の場合、これは/data/token にあるトークンを次のクエリに渡します:?nextpagetoken=<token>
トークンをリクエストボディに渡す必要がある場合、'pagetokenparam' をそのXPath に設定します。
<api:set attr="pagetokenpath" value="/request/nextpagetoken" />
他のページングの種類
API が説明したページングパターンのどれにも従わない場合は、カスタムページング実装が必要になります。 最初のページから必要な情報を'Rows@Next' 属性に設定します。出力に'Rows@Next' 値が設定されている場合、このページのすべての結果が返された後、本製品 は入力に'Rows@Next' 値を使用してこのメソッドを自動的に再度呼び出します。
この入力の値を使用して、次のパスのリクエストを変更して、次ページのデータを取得することができます。次ページのデータをリクエストするために必要なあらゆる情報にRows@Next 入力を設定します。
例えば、API がレスポンスに次のページのURL を返す場合、URL にXPath を指定することでこの値を取得できます。
<api:set attr="elementmappath#" value="/next_page" />
<api:set attr="elementmapname#" value="rows@next" />
値が設定されている場合は、リクエストが行われたURL を変更できます。api:check エレメントを使用して、Rows@Next 入力が値を持つかどうかを最初にチェックします。Rows@Next 入力は、_input アイテムの属性としてアクセスできます。
<api:check attr="_input.rows@next">
<api:set attr="uri" value="[_input.rows@next]" />
<api:else>
<api:set attr="uri" value="<first page's URL>" />
</api:else>
<api:check>
他のSELECT ステートメントをサーバー側で処理
任意のHTTP 要求をGET メソッドで作成できます。SELECT クエリの他のコンポーネントにアクセスするには、_query アイテムを使用します。次の表は、本製品 に発行されたクエリを説明するGET メソッド_query アイテムの属性を示します。
query | SQL クエリ。次に例を示します。
SELECT Id, Name FROM Accounts WHERE City LIKE '%New%' AND COUNTRY = 'US' GROUP BY CreatedDate ORDER BY Name LIMIT 10,50; |
selectcolumns | SELECT ステートメントで指定されたカラムを含むカンマ区切りのリスト。例えば、Id およびName カラムです。 |
table | SELECT ステートメントで指定されたテーブル名。例えば、Accounts です。 |
criteria | ステートメントのWHERE 句。
City LIKE '%New%' AND COUNTRY = 'US' |
orderby | ORDER BY 句で指定されたカラム。例えば、Name です。 |
groupby | SELECT ステートメントのGROUP BY 句。例えば、CreatedDate です。 |
limit | SELECT ステートメントのLIMIT またはTOP 句で指定されたリミット。例えば、50 です。 |
offset | SELECT ステートメントのLIMIT またはTOP 句で指定されたオフセット。例えば、10 です。 |
isjoin | クエリが結合かどうか。 |
jointable | 結合するテーブル。 |
isschemaonly | クエリがスキーマ情報のみを取得するかどうか。 |
サーバー上でLIMIT を処理
API がサポートしている場合は、LIMIT 句を実装して、サーバーから取得する必要がある結果の数を制限できます。
API リクエストを作成するときに、_query アイテムのlimit 属性の値を参照します。OData API では、$top クエリ文字列パラメータを使用して制限を指定できます。以下に示します。
http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$top=10
以下は対応するスクリプトです。
<api:check attr="_query.limit">
<api:set attr="uri" value="http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$top=[_query.limit]" />
</api:check>
キーワードリファレンス
このセクションで使われているキーワードの詳細情報は、API Script Reference を参照してください。