フロー変数の使用

このページの内容は ApigeeApigee ハイブリッドに該当します。

Apigee Edge のドキュメントを表示する。

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

フロー変数とは

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

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

一部の変数は Apigee に組み込まれており、API リクエストを受信するたびに自動的に入力されます。API トランザクション全体で利用できます。また、AssignMessage ポリシーなどのポリシーを使用するか、JavaScript や Java コードで独自のカスタム変数を作成することもできます。

ご覧のとおり変数にはスコープがあり、アクセスできる場所は、API プロキシフローのどこで変数が作成されたかによっても異なります。一般的に、変数が作成されると、API トランザクション フローにおいて後で実行されるすべてのポリシーとコードでその変数を使用できます。

フロー変数の使用方法

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

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

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

  • 条件フローでは、プログラミングにおけるスイッチ ステートメントと同様に、フロー変数を参照し、Apigee を介して API のフローを指示できます。

    たとえば、特定のフロー変数が設定された場合にのみ実行される、障害を返すポリシーが考えられます。

それぞれのコンテキストにおける変数の使用例を見てみましょう。

ポリシーのフロー変数

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

たとえば、次の 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.countmy-quota-policy は対象の Quota ポリシーの名前)です。

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

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

条件フローはフロー変数を評価し、プロキシが動的に動作できるようにします。条件は通常、フロー、ステップ、ルートルールの動作を変更するために使用されます。

ここでは、プロキシ フロー ステップで変数 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 のような変数はどこから来たのか、疑問に思われるかもしれません。いつインスタンス化され、値が代入されるのでしょうか。変数が作成されるタイミングと、使用可能になるタイミングについては、API プロキシのフローを可視化するをご覧ください。

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

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

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

JavaScript を使用して変数を読み取り、設定するこの手法は、前述した AssignMessage ポリシーで行える作業と似ています。Apigee で同じことをするための、別の方法です。注目すべき点は、JavaScript ポリシーで実行される JavaScript は、API プロキシフローに存在し、スコープ内にあるすべてのフロー変数にアクセスできることです。

API プロキシのフローの可視化

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

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

HTTP クライアント リクエストは API プロキシを介して HTTP サービスに送られ、レスポンスは API プロキシを介してクライアントに戻されます。

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

変数のスコープをプロキシフローに関連付ける方法

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

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

次の表に、変数のスコープをすべて記載し、それらがプロキシフロー内で使用可能になるタイミングを示します。

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

たとえば、client.ip という組み込み Apigee 変数があります。この変数には、プロキシ リクエスト スコープがあります。プロキシを呼び出したクライアントの 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 の組み込み変数はすべて、ドット表記の命名規則に従っています。この規則により、変数の目的を判断しやすくなります。たとえば、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 など、明確に定義されたデータ型があります。データ型はフロー変数のリファレンスに記載されています。ポリシーで作成された変数については、データ型の情報が記載された特定のポリシー リファレンスのトピックをご覧ください。

手動で作成した変数は、作成時に指定された型が想定され、許可される値のタイプに依存します。

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

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

プロキシとポリシーを使用する場合は、ポリシー リファレンスを参照して、作成される変数とその使用目的を確認してください。たとえば、Quota ポリシーは、割り当ての数と上限、有効期限などの情報を含む一連の変数を作成します。

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

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

次の例では、ExtractVariables ポリシーによってレスポンス メッセージが解析され、レスポンスから取得した特定のデータが格納されます。このポリシーでは 2 つのカスタム変数(geocoderesponse.latitudegeocoderesponse.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 オブジェクト モデルでは、Apigee で実行中の 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 コードで、プロキシフロー変数を取得または設定することもできます。

注意事項

フロー変数に関する重要なポイントは次のとおりです。

  • 一部の標準変数は、プロキシ自体によって自動的にインスタンス化され、値が代入されます。これはフロー変数のリファレンスに記載されています。
  • プロキシフローで使用可能なカスタム変数を作成できます。AssignMessage ポリシーJavaScript ポリシーなどのポリシーを使用して変数を作成できます。
  • 変数にはスコープがあります。たとえば、最初のプロキシがアプリからリクエストを受信すると、自動的に値が入力される変数もあります。その他の変数には、プロキシのレスポンス フロー セグメントで値が代入されます。これらのレスポンス変数は、レスポンス セグメントの実行まで未定義の状態に保たれます。
  • ポリシーが実行されると、ポリシー固有の変数が作成され、値が代入されます。各ポリシーのドキュメントには、これらの関連するポリシー固有の変数がすべてリストされています。
  • 条件フローは通常、1 つ以上の変数を評価します。条件フローを作成する場合は、変数への理解を深める必要があります。
  • 多くのポリシーは、入力または出力として変数を使用します。あるポリシーによって作成される変数が、後で別のポリシーによって使用されることもあります。

関連トピック

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