Send Docs Feedback

Note: Most user interface tasks can be performed in Edge Classic or the New Edge experience. For an overview, getting started topics, and release notes specific to the New Edge experience, see the docs.

フローの変数と条件

Conditional statements are a common control structure in all programming languages. Like a programming language, API proxy configuration supports conditional statements for Flows, Policies, Steps, and RouteRules. By defining conditional statements, you define dynamic behavior for your API. This dynamic behavior lets you do things like converting XML into JSON only for mobile devices, or routing to a backend URL based on the content type or HTTP verb of the request message.

このトピックでは、コードを作成することなく、条件を使用して API 管理機能を実行時に動的に適用する方法を示します。

条件文の構成

条件動作を API プロキシに実装するには条件変数を組み合わせて使用します。 条件文の作成には Condition 要素を使用します。以下に示したのは空の条件です。

<Condition></Condition>

条件文を作成するには、条件演算子と変数を追加して、以下のような構造を作成します。

<Condition>{variable.name}{operator}{"value"}</Condition>

サポートされている条件演算子には、= (等しい)、!= (等しくない)、> (以上) があります。 読みやすくするため、条件を文字で equalsnotequalsgreaterthan のように記述することもできます。

URI パスを操作する場合は、 ~/ または MatchesPath を使用できます。また、~~ 演算子を使って JavaRegex 正規表現と照合することもできます。

~~ 演算子の例については、次の Apigee Community のスレッドを参照してください:

https://community.apigee.com/questions/4284/how-do-you-override-at-the-end-of-the-url-when-you.html

条件は、バックエンド API リソースに対する API プロキシ条件フローを定義するのに使用します。これについては、「バックエンド API リソースへの条件フローのマップ」で説明しています。条件の一覧については、「Conditions reference」を参照してください。

Variables

条件は、変数の値を評価することでその機能を実行します。変数は、API プロキシによって実行される HTTP トランザクションのプロパティ、または API プロキシ構成そのもののプロパティです。API プロキシがアプリからのリクエストを取得するたび、Apigee Edge はシステム時間、アプリのネットワーク情報、メッセージ上の HTTP ヘッダー、API プロキシ構成、ポリシー実行などのものに関連付けられている長い変数リストを入力します。これにより、条件文の設定に使用できる豊富なコンテキストが作成されます。

変数には必ずドット表記が使用されます。例えば、リクエストメッセージ上の HTTP ヘッダーは request.header.{header_name} という変数として利用できます。したがって、Content-type ヘッダーの評価には変数 request.header.Content-type を使用できます。例えば、request.header.Content-type = "application/json" は、リクエストのコンテンツタイプが JSON でなければならないことを示しています。

 リクエストメッセージが GET の場合にのみポリシーが強制されるようにする条件文を作成する必要があるとします。以下のような条件文を作成すると、リクエストの HTTP 動詞を評価する条件を作成できます。この条件の変数は request.verb です。変数の値は GET です。演算子は = です。

<Condition>request.verb = "GET"</Condition>
また、以下のようにも記述できます。
<Condition>request.verb equals "GET"</Condition>

Edge は、このような文を使用して条件を評価します。上記の例は、リクエストに関連付けられている HTTP 動詞が GET の場合に true と評価されます。リクエストに関連付けられている HTTP 動詞が POST の場合、この文は false と評価されます。

Edge は、すべての HTTP ヘッダーおよびクエリーパラメータを、request.header. および request.queryparam.変数プリフィックスを使用してアクセスできる変数として自動的に格納します。

動的な動作を実現にするには、Condition を Flow、Step、RouteRule に添付します。

条件を Flow に添付すると、「条件 Flow」を作成したことになります。条件 Flow は、条件が true と評価された場合にのみ実行されます。条件 Flow には Policy をいくつでも添付できます。条件 Flow を使用すると、特定の条件に合致するリクエストまたはレスポンスメッセージ用のきわめて特化された処理ルールを作成できます。

例えば、リクエスト動詞が GET の場合にのみ実行される Flow は、以下のように作成します。

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
</Flows>

Flow を GET 用に 1 つ、POST 用に 1 つ作成する場合は、以下のようにします。

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
  <Flow name="ExecuteForPOSTs">
  <Condition>request.verb="POST"</Condition>
  </Flow>
</Flows>

以下の例に示すように、条件は Policy Step そのものに適用できます。以下の Condition により、VerifyApiKey Policy はリクエストメッセージが POST の場合にのみ強制されます。

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

このような条件 Flow を定義したら、そこに Policy を添付して、API プロキシで GET リクエストにはあるポリシーの一式、POST リクエストには別のポリシーの一式を強制するようにできます。

詳細については、以下を参照してください。

ペイロードの XML から JSON への条件付き変換

モバイルデバイスの場合に限ってレスポンスメッセージを XML から JSON に変換する必要がある、という例を考えてみましょう。まず、Weather API からの XML 形式のレスポンスを JSON に変換するポリシーを作成します。

<XMLToJSON name="ConvertToJSON">
  <Options>
  </Options>
  <OutputVariable>response</OutputVariable>
  <Source>response</Source>
</XMLToJSON>

上記のポリシー構成は API プロキシに対して、レスポンスメッセージを取得し、デフォルト設定で XML から JSON へ変換し、その結果を新しいレスポンスメッセージに書き出すよう指示します (リクエストメッセージを XML から JSON に変換する場合は、両方の値を request に設定するだけです)。

XMLToJSON ポリシータイプには、ある程度のデフォルトが一式定義されています。そのため、XML を特定の JSON 構造に仕立てるための構成要素を追加するだけで済みます。手順については、「XML to JSON ポリシー」を参照してください。

レスポンスを XML から JSON に変換したいので、変換を実行するための条件付きレスポンス Flow を構成する必要があります。例えば、すべてのレスポンスを XML から JSON に変換してからクライアントアプリに返すには、以下の ProxyEndpoint レスポンス Flow を構成します。

<Flows>
  <Flow name="Convert-for-devices">
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

標準のリクエストを使用して API を呼び出すと、レスポンスは JSON 形式になります。

ここで、目指している動作は要求側クライアントがモバイルデバイスの場合に限って Weather レポートを JSON に変換することです。このような動的な動作を実現するには、Flow に条件文を追加する必要があります。

条件動作の構成

以下の例に示されているのは Convert-for-devices という名前の単一の条件フローで、ProxyEndpoint のレスポンス Flow に構成されています。条件が適用されるエンティティに対し、Condition を要素として追加します。この例において、条件はこの Flow の構成要素の 1 つです。よって、この Flow はこの文が true と評価された場合にのみ実行されます。

<Flows>
  <Flow name="Convert-for-devices">
  <Condition>(request.header.User-Agent = "Mozilla")</Condition>
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

アプリから受信されたリクエストごとに、Edge は存在するすべての HTTP ヘッダーの値を変数として格納します。リクエストに User-Agent という名前の HTTP ヘッダーが含まれていた場合、そのヘッダーと値は request.header.User-Agent という変数として格納されます。

上記の ProxyEndpoint 構成が与えられると、Edge は request.header.User-Agent 変数の値を調べて、条件が true と評価されるかどうかを確認します。

条件が確かに true と評価された場合、言い換えると、変数 request.header.User-Agent の値が Mozilla に等しい場合、この条件 Flow が実行され、ConvertToJSON という名前の XMLtoJSON ポリシーが強制されます。true ではなかった場合、Flow は実行されず、XML レスポンスは変更されずに (XML 形式で) 要求側アプリに返されます。

条件フローのテスト

このサンプルリクエストにおいて、HTTP User-Agent ヘッダーは Mozilla に設定されており、そのため条件文が true と評価され、条件フロー Convert-for-devices が実行されます。

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

Python を利用できる場合に pretty print するには、以下のようにします。

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool

サンプルレスポンス:

. . .

"yweather_forecast": [
         {
              "code": "11", 
              "date": "12 Dec 2012", 
              "day": "Wed", 
              "high": "55", 
              "low": "36", 
              "text": "Showers" 
          }, 
          {
              "code": "32", 
              "date": "13 Dec 2012", 
              "day": "Thu", 
              "high": "56", 
              "low": "38", 
              "text": "Sunny"
          }
      ]
  }

. . .

User-Agent ヘッダーなしで送信されたリクエスト、または Mozilla 以外の値で送信されたリクエストに対しては、XML 形式のレスポンスになります。

$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

変更なしの XML レスポンスが返されます。

サンプルレスポンス:

<yweather:forecast day="Wed" date="12 Dec 2012" low="36" high="55" text="Showers" code="11" /> <yweather:forecast day="Thu" date="13 Dec 2012" low="38" high="56" text="Sunny" code="32" />

サンプル条件

RouteRule に添付された条件

<RouteRule name="default">
 <!--this routing executes if the header indicates that this is an XML call. If true, the call is routed to the endpoint XMLTargetEndpoint-->
  <Condition>request.header.content-type = "text/xml"</Condition>
  <TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>

ポリシーに添付された条件

<Step>
<!--the policy MaintenancePolicy only executes if the response status code is exactly 503-->
  <Condition>response.status.code = 503</Condition>
  <Name>MaintenancePolicy</Name>
</Step>

条件 Flow

<!-- this entire flow is executed only if the request verb is a GET-->
<Flow name="GetRequests">
  <Condition>request.verb="GET"</Condition>
  <Request>
    <Step>
<!-- this policy only executes if request path includes a term like statues-->
<Condition>request.path ~ "/statuses/**"</Condition>
      <Name>StatusesRequestPolicy</Name>
    </Step>
  </Request>
  <Response>
    <Step>
<!-- this condition has multiple expressions. The policy executes if the response code status is exactly 503 or 400-->
<Condition>(response.status.code = 503) or (response.status.code = 400)</Condition>
      <Name>MaintenancePolicy</Name>
    </Step>
  </Response>
</Flow>

条件における演算子の例

条件の作成に使用する演算子の例をいくつか示します。

  • request.header.content-type = "text/xml"
  • request.header.content-length < 4096 && request.verb = "PUT"
  • response.status.code = 404 || response.status.code = 500
  • request.uri MatchesPath "/*/statuses/**"
  • request.queryparam.q0 NotEquals 10

Help or comments?