SELECT 実行
SELECT クエリが発行されると、connector はスキーマのGET メソッドを実行します。これは、JSON を処理するためのconnector のビルトインオペレーションを呼び出します。GET メソッドでは、データの要求を制御できます。次のプロシージャは、これを使用するいくつかの方法を示します。SELECT WHERE を使ったサーバー側でのリモートデータの検索、サーバーから返される結果のLIMIT、またはページングを実装します。
JSON へのSelect の実行
次の手順を実行すると、SQL-92クエリを実行できるスクリプトが作成されます。クエリはクライアント側で処理されます。 データ処理操作を呼び出す前に、URI とJSONPath(オプション)を指定する必要があります。api:set キーワードを使って、これらの属性を宣言します。
-
URI 属性を、ローカルファイルまたはHTTP アクセス可能なアドレスに設定します。
<api:set attr="uri" value="NorthwindOData.json" />
-
必要であれば、JSONPath 属性を、個々の行を構成するデータのXPath に設定します。通常はオブジェクト配列です。デフォルトでは、connector はドキュメントをスキャンしてネストされたオブジェクト配列を検出します(階層データの解析 を参照してください)。
<api:set attr="JSONPath" value="$.people" />
-
GET メソッドで処理を呼び出します。スクリプトブロック内でapi:push キーワードを使用して処理を呼び出します。op パラメータを使って処理を指定します。このキーワードは、処理の結果をスキーマの出力にプッシュします。
<api:script method="GET"> <api:set attr="method" value="GET"/> <api:call op="jsonproviderGet"> <api:push /> </api:call> </api:script>
サーバー上でSELECT WHERE を処理
次のセクションでは、SELECT WHERE ステートメントをJSON API に対する検索リクエストに変換する方法を示します。プロシージャは次のステートメントを使用します。
SELECT * FROM <table> WHERE modifedAt < '2017-10-10' AND modifedAt > '2017-09-01'
このフィルタがクエリパラメータを介してサーバーでサポートされている場合は、api:info カラム定義のother:filter プロパティを使用して、希望するマッピングを指定できます。上記のクエリでは、このプロパティを使用して、modifiedAt < '<date>' フィルタを特定の日付より前に修正された結果を返すクエリパラメータにマッピングします。そして、modifedAt > '<date>' フィルタを後で修正された結果をフィルタリングするクエリパラメータにマッピングします。other:filter は次のように指定します。
- 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 自体は予測データの一部ではなく、以下のリクエストのようにリクエストURL に指定されます。
http://api.wunderground.com/api/{MyAPIKey}/hourly/q/MyLocation.json
次にSQL で表された予測クエリの例を示します。
SELECT * FROM Hourly WHERE Location="27516"
下記の手順に従って、Location 疑似カラムを追加し、先のクエリを実装します。
- ロケーション入力パラメータをapi:info ブロックのカラム定義に追加します。(Location は必須です。Location が指定されていない場合、connector はエラーをスローします。)
<api:info> ... <input name="Location" required="true"/> </api:info>
- _input アイテムのLocation 属性を参照して、URI を構築します。
<api:set attr='uri' value="http://api.wunderground.com/api/[_connection.APIKey]/hourly/q/[_input.Location].json"/>
- 処理を呼び出してリクエストを行い、レスポンスを処理します。
<api:script method="GET" > <api:push op="jsonproviderGet"/> </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' 属性をTRUE に設定する必要があります。
<api:set attr="EnablePaging" value="TRUE" />
ドライバーは4種類のページング実装を自動的にサポートします。1つ目は、次のページのURL がレスポンスに返されたときです。2つ目は、クエリパラメータに現在のページオフセットを指定するタイプです。3つ目は、クエリパラメータで現在のページ番号を送信するものです。4つ目は、次のリクエストのクエリパラメータにページトークンを送信する必要があります。API がこれらのページングパターンのいずれかを利用している場合は、以下の例に従ってページングを実装してください。
次ページのURL
サービスが次のページのURL をレスポンスボディやヘッダに返すときは、'pageurlpath' 属性をこのデータの場所に設定します。この場所に値が存在する場合は、次のリクエストのURL を設定するために使用されます。
- 次ページのURL がレスポンスボディに渡される場合は、'pageurlpath' をエレメントのXPath に設定します。
<api:set attr="pageurlpath" value="/data/nextPage" />
- 次ページのURL が'Link' ヘッダとともにレスポンスヘッダに渡される場合は、'pageurlpath' の前にheader: を付けてその場所を示すことができます。
返された'Link' ヘッダ値に部分的なURL パスが含まれている場合は、'BaseURI' 属性を、'Link' ヘッダで返されたURL パスの先頭に追加するベースURL に設定できます。
<api:set attr="pageurlpath" value="header:Link" />
ページングトークン
後続リクエストでページングパラメータに渡す必要があるトークンがレスポンスボディに返されることがあります。この場合は、'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" />
レコードオフセット
サービスがページングを制御するレコードオフセットクエリパラメータを提供する場合は、オフセットクエリパラメータの名前、ページサイズクエリパラメータの名前、および渡されるページサイズを設定することによってこれを実装できます。これを制御するパラメータがない場合は、ページサイズパラメータを設定する必要はありません。この場合、pagesize をデフォルトのページサイズに設定する必要があります。
<api:set attr="pageoffsetparam" value="offset" />
<api:set attr="pagesizeparam" value="limit" />
<api:set attr="pagesize" value="100" />
ページ番号
レコードオフセットと同様に、サービスがページ番号を設定するクエリパラメータを提供する場合は、ページ番号クエリパラメータの名前、ページサイズクエリパラメータの名前、および渡されるページサイズを設定することによってこれを実装できます。これを制御するパラメータがない場合は、ページサイズパラメータを設定する必要はありません。この場合、pagesize をデフォルトのページサイズに設定する必要があります。
<api:set attr="pagenumberparam" value="page" />
<api:set attr="pagesizeparam" value="pagesize" />
<api:set attr="pagesize" value="100" />
他のページングの種類
API がこれらのページングパターンのどれにも従わない場合は、カスタムページング実装が必要になります。これは、最初のページから必要な情報を'Rows@Next' 属性に設定することによって行われます。 出力に'Rows@Next' 値が設定されている場合、connector はこのページの結果を返した後、入力に'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 アイテムには、connector に発行されたクエリを表す次の属性があります。
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 を参照してください。