アンチパターン: API プロキシから Management API を呼び出す

Edge には「管理 API」と呼ばれる強力なユーティリティがあり、以下のようなサービスを提供します。

  • API プロキシのデプロイとデプロイ解除
  • 仮想ホスト、キーストア、トラストストアなどの構成
  • KeyValueMap、API プロダクト、デベロッパー アプリ、デベロッパー、コンシューマ キーなどのエンティティの作成、削除、更新
  • これらのエンティティの情報の取得

これらのサービスには、Apigee Edge プラットフォームの Management Server と呼ばれるコンポーネントを通じてアクセス可能です。これらのサービスはシンプルな管理 API 呼び出しを利用して簡単に呼び出せます。

ランタイム時に、API プロキシからこれらのサービスを使用しなければならない場合があります。これは、KeyValueMap、OAuth アクセス トークン、API プロダクト、デベロッパー アプリ、デベロッパー、コンシューマ キーなどのエンティティに、Key-Value ペアやカスタム属性の形式で、またはプロファイルの一部として、有益な情報が含まれているためです。

たとえば、KeyValueMap 内に以下のような情報を格納することによって、ランタイム時にセキュリティを確保しながらアクセス可能にすることができます。

  • バックエンドのターゲット URL
  • 環境プロパティ
  • バックエンドまたはサードパーティ システムのセキュリティ認証情報

同様に、ランタイム時に API プロダクトのリストやデベロッパーのメールアドレスを取得する場合があります。これらの情報は、デベロッパー アプリのプロファイルの一部として取得できます。

これらすべての情報をランタイム時に効果的に使用することによって、Apigee Edge 内のポリシーやカスタムコードで動的な動作を実現できます。

アンチパターン

管理 API は管理タスクを行うのに便利であり、推奨される方法です。しかし、API プロキシのフロー内でランタイム ロジックを実行するために管理 API を使用すべきではありません。その理由は次のとおりです。

  • KeyValueMap、OAuth アクセス トークンなどのエンティティに関する情報へのアクセス、または API プロキシの他の目的で管理 API を使用することは、Management Server への依存につながります。
  • Management Server は Edge ランタイム コンポーネントの一部ではないため、可用性がそれほど高くない場合があります。
  • また、Management Server は必ずしも同じネットワークやデータセンター内にプロビジョニングされるわけではありません。そのためランタイム時にネットワークのレイテンシが発生する場合があります。
  • Management Server 内のエントリがキャッシュされる期間は長いため、短期間に書き込みと読み込みを実行した場合、API プロキシで最新のデータをすぐに表示できない場合があります。
  • ランタイム時にネットワーク ホップが増加します。

以下のコードサンプルでは、JavaScript のカスタムコードを通じて管理 API を呼び出し、KeyValueMap から情報を取得します。

var response = httpClient.send('https://api.enterprise.apigee.com/v1/o/org_name/e/env_name/keyvaluemaps/kvm_name')

Management Server が利用不可の場合、管理 API を呼び出す JavaScript コードは失敗します。これにより、以降の API リクエストも失敗することになります。

影響

  • ランタイム時に Management Server への依存関係がさらに生じます。Management Server の障害は API 呼び出しに影響を与えます。
  • 管理 API のユーザー認証情報を、ローカルに、または暗号化された KVM などの安全な保存場所に保管する必要があります。
  • ネットワークを介して管理サービスを呼び出すことによるパフォーマンスの影響。
  • Management Server ではキャッシュの保存期間が長いため、最新の値がすぐに表示されない場合があります。

ベスト プラクティス

ランタイム時に、KeyValueMap、API プロダクト、デベロッパー アプリ、デベロッパー、コンシューマ キーなどのエンティティから情報を取得する効率的な方法は他にもあります。いくつかの例を示します。

  • KeyValueMapOperations ポリシーを使用して、KeyValueMap の情報にアクセスします。以下のサンプルコードは、KeyValueMap から情報を取得する方法を示しています。
    <!-- /antipatterns/examples/2-6.xml -->
        <KeyValueMapOperations mapIdentifier="urlMap" async="false"
            continueOnError="false" enabled="true" name="GetURLKVM">
          <DisplayName>GetURLKVM</DisplayName>
          <ExpiryTimeInSecs>86400</ExpiryTimeInSecs>
          <Scope>environment</Scope>
          <Get assignTo="urlHosti" index="2">
            <Key>
              <Parameter>urlHost_1</Parameter>
            </Key>
          </Get>
        </KeyValueMapOperations>
        
  • API プロダクト、デベロッパー アプリ、デベロッパー、コンシューマ キーなどの情報に API プロキシ内でアクセスするには、以下のいずれかの方法を利用します。
    • API プロキシのフローに VerifyAPIKey ポリシーがある場合は、このポリシーの一部として設定されたフロー変数を使用して情報にアクセスできます。以下のサンプルコードは、JavaScript を使用してデベロッパー アプリの名前と created_by の情報を取得する方法を示しています。
      <!-- /antipatterns/examples/2-7.xml -->
          print("Application Name ", context.getVariable(""verifyapikey. VerifyAPIKey.app.name"));
          print("Created by:", context.getVariable("verifyapikey. VerifyAPIKey.app.created_by"));
          
    • API プロキシのフローに VerifyAPIKey ポリシーがない場合は、Access Entity ポリシーと Extract Variables ポリシーを使用して、API プロダクトやデベロッパー アプリなどのプロファイルにアクセスできます。
      1. AccessEntity ポリシーを使用して DeveloperApp のプロファイルを取得します。
        <!-- /antipatterns/examples/2-8.xml -->
            <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
            <AccessEntity async="false" continueOnError="false" enabled="true" name="GetDeveloperApp">
              <DisplayName>GetDeveloperApp</DisplayName>
              <EntityType value="app"></EntityType>
              <EntityIdentifier ref="developer.app.name" type="appname"/>
              <SecondaryIdentifier ref="developer.id" type="developerid"/>
            </AccessEntity>
            
      2. ExtractVariables ポリシーを使用して、DeveloperApp から appId を抽出します。
        <!-- /antipatterns/examples/2-9.xml -->
            <ExtractVariables name="Extract-Developer App-Info">
              <!--
                The source element points to the variable populated by AccessEntity policy.
                The format is <policy-type>.<policy-name>
                In this case, the variable contains the whole developer profile.
              -->
              <Source>AccessEntity.GetDeveloperApp"</Source>
              <VariablePrefix>developerapp</VariablePrefix>
              <XMLPayload>
                <Variable name="appld" type="string">
                  <!-- You parse elements from the developer profile using XPath. -->
                  <XPath>/App/AppId</XPath>
                </Variable>
              </XMLPayload>
            </ExtractVariables>
            

関連情報