API コンシュームの拡張とネットワークトラフィックの最小化

受信ネットワークトラフィックの量を減らし、API をコンシュームしやすくするには、​$expand​ システムクエリオプションを使用します。API コンシューマーはクエリ結果の関連エンティティのインライン表現のみを要求するため、返される情報は複数のネットワーク往復処理を回避します。このクエリオプションを使用すると、従量制課金でレイテンシーの影響を受けるコンシューマーにメリットをもたらします。

APIkit for OData 1.3.0 以降、このモジュールは自動ルーティングをサポートし、最も一般的なケースで ​$expand​ システムクエリオプションを簡単に実装できます。この機能にはより多くの準備と設定が必要ですが、​$expand​ 要求を処理するときに、実装されたフローを再利用できます。

システムクエリオプションについての詳細は、 OASIS 仕様Leaving the Site​を参照してください。

始める前に

$expand​ 機能を使用するには、次の要件を満たす必要があります。

  • APIkit for OData Module (バージョン 1.3.0)

  • 各展開可能なエンティティの ​<request-entity-collection-listener/>​ 実装

  • <request-entity-collection-listener/>​ フローの ​in​ 検索条件のサポート

$expand​ 機能の例

例について説明します。

  • Employee​ エンティティには関連する ​Manager​ エンティティがある。

  • Employees​ エンティティセットは ​Employee​ エンティティの集合である。

  • Managers​ エンティティセットは ​Manager​ エンティティの集合である。

  • API の場所は ​https://example.com/api/​。

この設定を前提として、次の要求で従業員とそのマネージャーを取得します。

  • GET https://example.com/api/Employees​ を使用して、従業員のリストを取得する。

  • リレーションの ​ReferentialConstraint​ を介して ​Manager​ ID を収集する。

  • GET https://example.com/api/Managers?$filter=ManagerID in (id1, id2, ..., idN)​ を使用して、関連するマネージャーのリストを取得する。

  • 結合条件に基づいて、リストをマージする小さなプログラムを記述する。

$expand​ 機能を使用する場合、​Manager​ ナビゲーションプロパティが展開された従業員のリストを取得する要求は ​GET https://example.com/api/Employees?$expand=Manager​ です。

generic expand​ 機能

generic expand​ 機能を使用して、既存のフロー実装を展開要求の開始点として再利用します。この機能により、モジュールが ​$expand​ 項目を確実に完了するために必要な手順を実行している間、関連するデータ取得操作に集中できます。

generic expand​ 機能が有効になっているアプリケーションは、他の OData Mule アプリケーションと同様に機能します。ただし、フローの実行中に、モジュールがメインエンティティセットの情報を取得すると、​expand​ 項目の情報を収集するための追加の内部要求を実行します。

展開操作中にソフトウェアがエラーを処理する方法を設定できます。

  • 要求をエラーで失敗させる。

  • 失敗した展開を ​null​ 値に置き換える。

generic expand​ 操作

generic expand​ 機能は、元のフローが完了すると、追加のクエリをアプリケーションにディスパッチします。これはアプリケーション ​EDM​ に基づいて行われるため、追加のアノテーションを作成してモジュールに十分なコンテキストを追加する必要があります。

  • 展開が行われる ​EntitySet​ には、その ​Entity​ のすべての展開可能な ​NavigationProperty​ に対する ​NavigationPropertyBinding​ があります。

    これは、そのプロパティを展開するときに実行される ​<entity-collection-source/>​ を選択するために使用されます。

  • 展開可能な各 ​NavigationProperty​ には、​ReferentialConstraint​ が添付されています。

    Property​ の値を ​ReferencedProperty​ の値と照合する場合、内部要求は ​ReferentialConstraint​ を使用します。

フロー実行

  1. メインフローが実行されて完了すると、​entities​ のコレクションが生成されます。

  2. OData Module は、展開が必要なすべてのプロパティを収集します。

  3. 各 ​NavigationProperty​ で、次の手順を実行します。

    1. ReferentialConstraint​ から ​source property​ を取得します。

    2. ReferentialConstraint​ から ​referenced property​ を取得します。

    3. NavigationPropertyBinding​ から ​destination entity set​ を取得します。

    4. 各 ​entities​ で解決された ​source property​ を取得します。これらの値を ​source property list​ に追加します。

    5. (…​source property list)​ の ​$filter=referenced property​ を使用して ​destination entity set​ の ​<entity-collection-source/>​ を呼び出すことで、内部要求を実行します。

エラー処理とエラーの伝達

OData v4 アプリケーションのエラー処理は、​generic expansion​ を使用するかどうかに関係なく、各フローに対してローカルです。特定の ​EntitySet​ のエラー処理コードは、通常の要求と展開処理中に確認される内部要求のどちらの場合も、そのエンティティセットのフロー実装に属します。

展開プロセスはフローの実行が終了した後に実行されるため、展開プロセス中のエラー処理はサポートされていません。エラー処理で使用できる 2 つのオプションがあります。

  • Ignore errors during expansion (展開中にエラーを無視):​ 一般的展開中のエラーは無視されます。
    デフォルトでは、コレクションと単一オブジェクトの展開は、それぞれ空のリストと ​null​ 値に解決されます。

  • Propagate errors during expansion (展開中にエラーを伝達):​ 一般的展開中にエラーが発生します。
    エラーが OData v4 ルーターに到達すると、元の要求に対してエラー応答が返されます。

[Capabilities (機能)]​ タブで、​ソースごと​にエラー処理を設定できます。

制限事項

  • 最初の ​ReferentialConstraint​ のみが考慮されます。

    複合キーを使用するナビゲーションプロパティはサポートされていません。

  • 展開は、​EntitySet-by-EntitySet​ ではなく ​field-by-field​ で行われます。

    これにより、必要以上の内部要求が発生する可能性があります。

  • 展開されたエンティティには常に ​<entity-collection-source/>​ 実装があります。

    <entity-source/>​ 実装を使用した展開は、パフォーマンス上の問題により実行されません。

実装のガイドライン

generic expansion​ 機能を実装するには、展開できる種別で各ソースにアノテーションを付ける必要があります。制限なしで ​$expand​ を有効にすると、API クライアントが複雑なクエリを記述できるようになり、パフォーマンスの問題が発生する可能性があります。

一部のリレーションに対して ​$expand​ を手動で実装する場合は、これらのリレーションを ​[Expandable Navigation Properties (展開可能なナビゲーションプロパティ)]​ オプションのリストから除外します。​generic expansion​ 機能を使用しないナビゲーションプロパティは、フロー内で手動で実装する必要があります。

実装チェックリスト

  1. CSDL ファイルと Mule アプリケーションが期待される要件を満たしていることを確認します。

    • すべての ​NavigationProperty​ に 1 つの ​ReferentialConstraint​ がある。

    • すべての ​EntitySet​ にそのエンティティ種別の各 ​NavigationProperty​ に対して 1 つの ​NavigationPropertyBinding​ がある。

    • すべての ​<entity-collection-source/>​ で ​$filter​ システムクエリオプションの ​in​ 演算子がサポートされている。

  2. generic expand​ サポートを有効にする各ソースで、次の手順を実行します。

    1. [Capability (機能)]​ タブを開きます。

    2. [Expandable navigation properties (展開可能なナビゲーションプロパティ)]​ 項目をインラインで編集します。

    3. generic expand​ を使用して展開可能にする各ナビゲーションプロパティの名前を追加します。

    4. ユースケースに応じて、​[Ignore errors on expand (展開時にエラーを無視)]​ をオンにして、一般的展開中のエラーを回避し、メインフローでエラーを生成します。

  3. 既存のフローで ​$expand​ 機能がサポートされていることを確認します。