フロー変数の使用

フロー変数は、ポリシーまたはユーティリティ(Trace ツールツールなど)内からアクセスできるオブジェクトと考えることができます。これを使用することにより、Apigee Edge によって処理された API トランザクションに関連付けられている状態を保持できます。

フロー変数とは

フロー変数は、API プロキシフローのコンテキスト内に存在し、名前付き変数がソフトウェア プログラム内で状態を追跡するのと同じ方法で、API トランザクション内で状態を追跡します。フロー変数には、以下のような情報が格納されます。

  • IP アドレス、ヘッダー、URL パス、リクエスト側のアプリケーションから送信されるペイロード
  • Edge がリクエストを受信した日時などのシステム情報
  • ポリシー実行時に派生したデータ。たとえば、OAuth トークンを検証するポリシーが実行された後、Edge はリクエスト側のアプリケーションの名前などの情報を保持するフロー変数を作成します。
  • ターゲット システムからのレスポンスに関する情報

一部の変数は Edge の「組み込み」変数になっており、API リクエストの受信時に常に値が自動的に代入されます。これらの変数は、API トランザクション全体を通じて利用できます。また、AssignMessage ポリシーなどのポリシーを使用して、あるいは JavaScript、Node.js、Java コードで、独自のカスタム変数を作成することもできます。

後述するように変数にはスコープがあり、アクセスできる場所は、ある程度、API プロキシフローで作成されたタイミングに応じて異なります。一般的に、変数が作成されると、API トランザクション フローにおいて後で実行されるすべてのポリシーとコードでその変数を使用できます。

フロー変数の使い方

フロー変数は、ポリシー条件付きフローで使用されます。

  • ポリシーは、フロー変数から状態を取得して、これらの情報に基づいて処理を行うことができます。

    たとえば、VerifyJWT ポリシーは、フロー変数から検証すべきトークンを取得して、このトークンで検証を実行できます。別の例としては、JavaScript ポリシーはフロー変数を取得して、これらの変数に含まれているデータをエンコードできます。

  • 条件フローは、プログラミングで switch ステートメントを使用する場合と似た方法で、フロー変数を参照して API のフローを Edge 経由に誘導できます。

    たとえば、障害を返すポリシーは、特定のフロー変数が設定された場合にのみ実行されます。最後に、Node.js ターゲット アプリケーションでは、フロー変数を取得および設定できます。

以下のそれぞれの状況で、変数がどのように使用されるか、例を見てみましょう。

ポリシーでのフロー変数

一部のポリシーは、入力としてフロー変数を取得します。

たとえば、以下の AssignMessage ポリシーは、フロー変数値 client.ip を取得して My-Client-IP というリクエスト ヘッダーに埋め込みます。リクエスト フローに追加される場合、このポリシーはバックエンド ターゲットに渡されるヘッダーを設定します。レスポンス フローで設定される場合、ヘッダーはクライアント アプリケーションに返送されます。

<AssignMessage name="set-ip-in-header">
        <AssignTo createNew="false" transport="http" type="request">request</AssignTo>
        <Set>
            <Headers>
                <Header name="My-Client-IP">{client.ip}</Header>
            </Headers>
        </Set>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    </AssignMessage>

もう 1 つの例では、Quota ポリシーの実行時に、一部のフロー変数にポリシー関連値が代入されます。このような変数の 1 つは、ratelimit.my-quota-policy.used.count という変数です(my-quota-policy は、使用する割り当てポリシーの名前です)。

「現在の割り当てカウントが最大値の 50% を下回っており、午前 9 時から午後 5 時までの間であれば、異なる割り当てを適用する」という条件フローを後で実行できます。この条件は、現在の割り当てカウントの値と system.time というフロー変数(これは組み込み Edge 変数の 1 つです)に基づいています。

条件フローでのフロー変数

条件フローは、フロー変数を評価して、プロキシに動的な振る舞いをさせることを可能にします。条件は一般的に、フロー、ステップ、ルートルールの動作を変更するために使用されます。

ここでは、プロキシフロー ステップで変数 request.verb の値を評価する条件フローについて説明します。この例では、リクエスト動詞が POST である場合、VerifyApiKey ポリシーが実行されます。これは API プロキシ構成で使用される一般的なパターンです。

<PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>request.verb equals "POST"</Condition>
                <Name>VerifyApiKey</Name>
            </Step>
        </Request>
    </PreFlow>

ここで疑問に思われるかもしれませんが、request.verbclient.ipsystem.time のような変数はどこから来たのでしょうか。これらはいつインスタンス化され、値が代入されるのでしょうか。変数が作成されるタイミングや利用可能になるタイミングについて理解するには、フロー変数のスコープについてをご覧ください。

JavaScript ポリシーで呼び出される JavaScript コードでのフロー変数

JavaScript ポリシーでは、API プロキシフローのコンテキストから JavaScript コードを実行できます。このポリシーで実行される JavaScript は、Apigee JavaScript オブジェクト モデルを使用します。このモデルにより、カスタムコードからリクエスト、レスポンス、コード実行中の API プロキシフローと関連付けられたコンテキスト オブジェクトに対するアクセスが可能になります。たとえば、次のコードは、フロー変数 target.name から取得した値でレスポンス ヘッダーを設定します。

context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"));

変数の読み取りと設定に JavaScript を使用するこの方法は、AssignMessage ポリシーで実行できる前述の方法と似ています。これは、同じ種類の処理を Edge で実行するもう 1 つの方法です。注目すべき点は、JavaScript ポリシーで実行される JavaScript は、API プロキシフローに存在していてスコープ内にあるすべてのフロー変数にアクセスできることです。

Node.js コードでのフロー変数

apigee-access モジュールを require することで、Edge にデプロイされた Node.js コード内からフロー変数を設定したり、フロー変数にアクセスしたりできます。

ここでは、custom.foo という変数を値 Bar に設定する簡単な例について説明します。一度設定すると、この新しい変数は、任意のポリシーや、Node.js コードの実行後にプロキシフローに出現するその他のコードで利用できます。

var http = require('http');
    var apigee = require('apigee-access');

    http.createServer(function (request, response) {
      apigee.setVariable(request, "custom.foo", "Bar");
      response.writeHead(200, {'Content-Type': 'text/plain'});
      response.end('Hello World\n');
    }).listen(8124);

    console.log('Server running at http://127.0.0.1:8124/');

変数を操作するために apigee-access を使用する方法については、Node.js でのフロー変数へのアクセスで確認できます。

フロー変数のスコープについて

変数のスコープは、フローまたは API プロキシ呼び出しの「ライフサイクル」全体に関連しています。

API プロキシのフローを可視化する

フロー変数のスコープの理解を深めるには、API プロキシ経由でメッセージが転送される仕組みを理解または可視化することが重要です。API プロキシは、フローとして構成された一連のメッセージ処理ステップで構成されています。プロキシフローの各ステップで、プロキシは利用可能な情報を評価して、次に何を実行するかを判定しています。この過程で、プロキシはポリシーコードを実行することや、条件分岐を実行することができます。

次の図では、この一連のフローを示します。フローは、ProxyEndpoint リクエスト、TargetEndpoint リクエスト、TargetEndpoint レスポンス、ProxyEndpoint レスポンスという 4 つの主要なセグメントで構成されていることに注目してください。

このトピックの後半では、このフロー構造を念頭に置いてフロー変数について見ていきましょう。

変数のスコープとプロキシフローが関連している仕組み

前述のように、プロキシ経由でメッセージが転送される仕組みを可視化すると、変数のスコープも理解しやすくなります。スコープという概念は、プロキシフローのライフサイクルで、変数が最初にインスタンス化されるポイントを表しています。

たとえば、ポリシーが ProxyEndpoint リクエスト セグメントに接続されている場合、このポリシーは、スコープが TargetEndpoint リクエスト セグメントに設定されている変数にはアクセスできなくなります。その理由は、フローの TargetEndpoint リクエスト セグメントがまだ実行されていないため、API プロキシがそのスコープの変数に値を代入する機会がないからです。

次の表にそれぞれの変数のスコープを示して、プロキシフロー内でこれらが利用可能になるタイミングについて説明します。

変数のスコープ これらの変数に値が代入される場所
プロキシ リクエスト ProxyEndpoint リクエスト セグメント
ターゲット リクエスト TargetEndpoint リクエスト セグメント
ターゲット レスポンス TargetEndpoint レスポンス セグメント
プロキシ レスポンス ProxyEndpoint レスポンス セグメント
常に利用可能 プロキシがリクエストを受信した時点。これらの変数は、プロキシフローのライフサイクル全体で利用可能です。

たとえば、client.ip という組み込み Edge 変数があります。この変数のスコープは「プロキシ リクエスト」です。この変数には、プロキシを呼び出したクライアントの IP アドレスが自動的に代入されます。リクエストが最初に ProxyEndpoint をヒットした時点で値が代入され、プロキシフローのライフサイクル全体で利用可能になります。

他に、target.url という組み込み変数があります。この変数のスコープは「ターゲット リクエスト」です。この変数には、TargetEndpoint リクエスト セグメントで、バックエンド ターゲットに送信されたリクエスト URL が値として代入されます。ProxyEndpoint リクエスト セグメントで target.url にアクセスしようとすると、NULL 値を受け取ることになります。スコープに至る前にこの変数を設定しようとしても、プロキシは何も行いません。つまり、エラーは生成されず、変数は設定されません。

ここでは、変数のスコープをどのように考えるべきか、簡単な例で説明していきます。リクエスト オブジェクトの内容全体(ヘッダー、パラメータ、本文)をコピーして、呼び出し元アプリケーションに返信するレスポンス ペイロードに割り当てると仮定します。このタスクには AssignMessage ポリシーを使用できます。ポリシーコードは次のようになります。

<AssignMessage name="CopyRequestToResponse">
        <AssignTo type="response" createNew="false">response</AssignTo>
        <Copy source="request"/>
    </AssignMessage>

このポリシーは、request オブジェクトを単純にコピーして、response オブジェクトに割り当てています。ただし、プロキシフロー内でこのポリシーはどこに配置すべきでしょうか。レスポンス変数のスコープが「ターゲット レスポンス」であるため、答えとしては TargetEndpoint レスポンスに配置する必要があります。

フロー変数の参照

Apigee Edge のすべての組み込み変数は、ドット表記の命名規則に従っています。この規則により、変数の目的をより簡単に明示できます。たとえば、system.time.hourrequest.content です。

Apigee では、関連する変数を適切に整理するために、さまざまな接頭辞を予約しています。次のような接頭辞があります。

  • request
  • response
  • system
  • target

ポリシーで変数を参照するには、中かっこで囲みます。たとえば、次の AssignMessage ポリシーは、変数 client.ip の値を取得して、Client-IP というリクエスト ヘッダーに埋め込みます。

<AssignMessage name="set-ip-in-header">
        <AssignTo createNew="false" transport="http" type="request">request</AssignTo>
        <Set>
            <Headers>
                <Header name="Client-IP">{client.ip}</Header>
            </Headers>
        </Set>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    </AssignMessage>

条件フローでは、中かっこは必要ありません。次の例の条件は、変数 request.header.accept を評価します。

<Step>
        <Condition>request.header.accept = "application/json"</Condition>
        <Name>XMLToJSON</Name>
    </Step>

また JavaScript および Java コードでもフロー変数を参照できます。詳細については、次をご覧ください。

フロー変数のデータ型

フロー変数の各プロパティには、String、Long、Integer、Boolean、Collection など、明確に定義されたデータ型があります。データ型はフロー変数のリファレンスにリストされています。ポリシーで作成された変数については、データ型の情報が記載された特定のポリシー リファレンスのトピックをご覧ください。

手動で作成する変数は、作成時に指定された型を継承します。また、使用可能な値の型に基づいて決定されます。たとえば、Node.js コードで作成される変数は、Number、String、Boolean、null、undefined に制限されます。

ポリシーでのフロー変数の使用

多くのポリシーは、通常の実行の一環としてフロー変数を作成します。ポリシー リファレンスには、これらのポリシー固有の変数がすべて記載されています。

プロキシとポリシーを操作する場合は、ポリシー リファレンスを参照して、作成される変数とその使用目的を必ず確認してください。たとえば、Quota ポリシーでは複数の変数が作成され、割り当てカウントと制限、有効時間などの情報が格納されます。

一部のポリシー変数はデバッグに役立ちます。たとえば、Trace ツールを使用して、プロキシフロー内の特定のインスタンスでどの変数が設定されたかを確認できます。

ExtractVariables ポリシーでは、メッセージから抽出されたデータをカスタム変数に代入できます。クエリ パラメータ、ヘッダーなどのデータを抽出できます。たとえば、特定のデータをメッセージから抽出するために、パターンを使用してリクエストおよびレスポンス メッセージを解析できます。

次の例では、ExtractVariables によってレスポンス メッセージが解析され、レスポンスから取得した特定のデータが格納されます。このポリシーでは 2 つのカスタム変数 geocoderesponse.latitude および geocoderesponse.longitude が作成され、値が割り当てられます。

<ExtractVariables name="ParseGeocodingResponse">
      <Source>response</Source>
      <VariablePrefix>geocoderesponse</VariablePrefix>
      <JSONPayload>
        <Variable name="latitude">
          <JSONPath>$.results[0].geometry.location.lat</JSONPath>
        </Variable>
        <Variable name="longitude">
          <JSONPath>$.results[0].geometry.location.lng</JSONPath>
        </Variable>
      </JSONPayload>
    </ExtractVariables>

ここでもう一度、多くのポリシーが自動的に変数を作成することに注目してください。このような変数には、プロキシフローのコンテキストでアクセスできます。また、このような変数については、ポリシー リファレンスにおいて、それぞれ個別のポリシー トピックで情報が提供されています。

JavaScript コードでのフロー変数の操作

API プロキシのコンテキストで実行している JavaScript コードでは、変数に対し直接アクセス、設定を行うことができます。Apigee JavaScript オブジェクト モデルでは、Edge 上で実行中の JavaScript は、プロキシフロー変数に直接アクセスできます。

JavaScript コードで変数にアクセスするには、以下のオブジェクトのいずれかで getter/setter メソッドを呼び出します。

  • context
  • proxyRequest
  • proxyResponse
  • targetRequest
  • targetResponse

すでにお気づきでしょうが、こうしたオブジェクト参照は、API プロキシのフローを可視化するで前述したプロキシフロー モデルのセグメントに対応しています。

context オブジェクトは、システム変数など、「グローバルに」利用できる変数に対応しています。たとえば、context オブジェクトで getVariable() を呼び出して現在の年を取得できます。

var year = context.getVariable('system.time.year');

同様に、setVariable() を呼び出して、カスタム変数の値を設定することや、書き込み可能な標準変数の値を設定することができます。ここでは、organization.name.myorg というカスタム変数を作成して、値をこの変数に割り当てます。

var org = context.setVariable('organization.name.myorg', value);
    

この変数は context オブジェクトで作成されるため、すべてのフロー セグメントで使用できます。基本的に、これはグローバル変数の作成に似ています。

JavaCallout ポリシーで実行する Java コードで、プロキシフロー変数を取得および設定することもできます。

Node.js アプリケーションでフロー変数にアクセスする

Edge にデプロイされた Node.js コードから、フロー変数を取得、設定、削除できます。必要な操作は、コードで apigee-access モジュールを「require」することだけです。詳しくは、Node.js でのフロー変数へのアクセスをご覧ください。

留意事項

フロー変数に関して、ここでは重要な留意事項をいくつか説明します。

  • 一部の「標準」変数は、プロキシ自体により自動的にインスタンス化され、値が代入されます。これらについてはフロー変数のリファレンスで説明されています。
  • プロキシフローで利用可能なカスタム変数を作成できます。AssignMessage ポリシーJavaScript ポリシーなどのポリシーを使用して、および Node.js コードで、変数を作成できます。
  • 変数にはスコープがあります。たとえば、最初のプロキシがアプリケーションからリクエストを受信すると、一部の変数には自動的に値が代入されます。別の変数には、プロキシのレスポンス フロー セグメントで値が代入されます。これらのレスポンス変数は、レスポンス セグメントの実行まで未定義の状態に保たれます。
  • ポリシーが実行されると、ポリシー固有の変数が作成され、値が代入されます。各ポリシーのドキュメントには、これらの関連するポリシー固有の変数がすべてリストされています。
  • 条件フローは、一般的に 1 つ以上の変数を評価します。条件フローを作成する場合は、変数への理解を深める必要があります。
  • 多くのポリシーは、入力または出力として変数を使用します。一般的に、あるポリシーで作成される変数は、後で別のポリシーによって利用されます。
  • 純正の JavaScript(および JavaScript オブジェクト モデル)、または Edge でコードを実行する JavaCallout ポリシーを使用して、Node.js で多くのフロー変数を取得および設定できます。

関連コードサンプル

API プロキシのサンプルは GitHub にあり、簡単にダウンロードして利用できます。サンプルのダウンロードと使い方については、サンプル API プロキシの使用をご覧ください。API プロキシのサンプルの説明と機能については、サンプルリストをご覧ください。

変数の使用と変数の処理を特徴とするサンプル プロキシ:

  • variables - 転送、JSON、XML メッセージのコンテンツに基づいて変数を抽出および設定する方法について説明します。
  • policy-mashup-cookbook - ポリシーの作成機能を使用する完成度の高いアプリケーションです。2 つの公開 API を呼び出し、処理結果を結合して、クライアント アプリケーション向けに詳細なレスポンスを生成します。このサンプルについて詳しくは、ポリシー作成機能の使用をご覧ください。
  • conditional-policy - 変数値に基づく簡単な条件ポリシーの適用を実装します。

関連トピック

  • API プロキシで値が自動的に代入される変数は、すべてフロー変数のリファレンスにリストされています。このリファレンスには、各変数の型とスコープもリストされています。
  • 特定のポリシーで値が代入される変数を確認する場合は、ポリシーのリファレンス トピックをご覧ください。たとえば、Quota ポリシーのリファレンスのフロー変数をご覧ください。