Send Docs Feedback

Conditions reference

Conditions enable API proxies to behave dynamically at runtime. Conditions define operations on variables, which are evaluated by the Apigee Edge processing pipeline. Conditional statements are boolean and always evaluate to true or false.

For a tutorial-like topic that explains how to use pattern matching in conditional statements, see Pattern matching in conditional statements.

Use of variables in conditional statements

Developers commonly use both built-in flow variables and custom variables in conditional statements.  For a complete list of the built-in variables, see Variables reference.  For instructions, see on setting custom variables, see Extract Variables policy

Structure of conditional statements

The basic structure of a conditional statement is:

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

For example:

<Condition>request.verb = "GET"</Condition>

Conditions can be chained. For example, the following condition evaluates to true only if the URI of the request matches /statuses/user_timeline.json and the HTTP verb of the request is GET.

<Condition>(proxy.pathsuffix MatchesPath "/statuses") and (request.verb = "GET")</Condition>

Or:

(proxy.pathsuffix MatchesPath "/statuses") and (request.verb != "GET")

Where you can use conditional statements

You can use conditions to implement conditional behavior to control:

  • policy execution
  • flow execution
  • target endpoint route selection

Policy execution

Using conditional statements, you can control the enforcement of policies. A common use case is conditional transformation of response messages, based on HTTP header or message content.

For example, to conditionally transform XML to JSON based on the Accept header:

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

Flow execution

Using conditional statements, you can control the execution of named flows in ProxyEndpoints and TargetEndpoints. Note that only 'named' flows can be executed conditionally. Preflows and postflows (both request and response) on ProxyEndpoints and TargetEndpoints execute for every transaction, and thus provide unconditional 'failsafe' capabilities.

For example, to execute a conditional request flow based on the HTTP verb of the request message, and conditional response flow based on a (potential) HTTP status code representing an error:

<Flow name="GetRequests">
  <Condition>request.verb = "GET"</Condition>
  <Request>
    <Step>
      <Condition>request.path MatchesPath "/statuses/**"</Condition>
      <Name>StatusesRequestPolicy</Name>
    </Step>
  </Request>
  <Response>
    <Step>
      <Condition>(response.status.code = 503) or (response.status.code = 400)</Condition>
      <Name>MaintenancePolicy</Name>
    </Step>
  </Response>
</Flow>

Target endpoint route selection

Using conditional statements, you can control the target endpoint invoked by proxy endpoint configuration. A route rule forwards a request to a particular target endpoint. When more than one target endpoint is available, the route rule is evaluated for its condition and, if true, the request is forwarded to the named target endpoint.

For example, to conditionally route messages to designated target endpoints based on Content-Type:

<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>

See Create dynamic API flows using conditions for more information.

Path Expressions

Path expressions are used for matching URI paths, using "*" to represent a single path element and "**" to represent multiple URI levels.

For example:

Pattern Sample URI paths matched
/*/a/ /x/a/ or /y/a/
/*/a/* /x/a/b or /y/a/foo
/*/a/** /x/a/b/c/d
/*/a/*/feed/ /x/a/b/feed/ or /y/a/foo/feed/
/a/**/feed/** /a/b/feed/rss/1234

% is treated as an escape character. The pattern %{user%} matches {user} but not user.

Conditions can be categorized as follows:

  • Operators: Wildcard patterns used in conditions.
  • Relational operands: Evaluates whether a quantity is equal to, greater than, or less than another.
  • Operands: The value of the conditions is used to determine the overall values.
  • Literals: Literal values in a condition.

Operators

When using operators, observe the following restrictions:

  • Operators cannot be used as variable names.
  • A space character is required before and after an operator.
  • To include an operator in a variable, a variable name must be enclosed in single quotes. For example, 'request.header.help!me'.
  • Arithmetic operators (+, *, -, /, %) are not supported.
  • Java precedence is used for operators.
  • Apigee Edge relies on regular expressions as implemented in java.util.regex.
Symbol In words (case insensitive) Description
! Not, not Unary operator (takes a single input)
= Equals, Is Equals to
!= NotEquals, IsNot Not equals
:= EqualsCaseInsensitive Equals but is case insensitive
> GreaterThan Greater than
>= GreaterThanOrEquals Greater than or equal to
< LesserThan Lesser than
<= LesserThanOrEquals Lesser than or equal to
&& And, and And
|| Or Or
(   Groups an expression
)   Closes an expression group
~~ JavaRegex

Matches a javax.util.regex compliant regular expression. For examples, see Pattern matching in conditional statements.

~ Matches, Like Matches a glob-style pattern using the "*" wildcard character. For examples, see Pattern matching in conditional statements.
~/ MatchesPath, LikePath Matches a path expression. For examples, see Pattern matching in conditional statements.
=| StartsWith Starts with

Behavior of null operands in conditional statements

The following table shows the behavior when operands evaluate to null:

Operator LHS null RHS null LHS and RHS null
=, ==, := false false true
=| false false false
!= true true false
> true false false
>= false true true
< true false false
<= true false true
~ false N/A false
~~ false N/A false
!~ true false false
~/ false N/A false

Operands

Apigee Edge adapts operands to a common data type before comparing them. For example, if the response status code is 404, the expression response.status.code = "400" and the response.status.code = 400 are equivalent.

For numeric operands, the data type is interpreted as integer unless the value is terminated as follows:

  • "f" or "F" (float, for example, 3.142f, 91.1F)
  • "d" or "D" (double, for example, 3.142d, 100.123D)
  • "l" or "L" (long, for example, 12321421312L)

In these cases, the system performs the adaptations shown in the following table.

Note: The dash character ( - ) in this table implies that the comparison is not performed, so the comparison is false.

RHS LHS Boolean Integer Long Float Double String Comparable Object
Boolean Boolean Integer Long Float Double String   -
Integer Integer Integer Long Float Double String Comparable -
Long Long Long Long Float Double String Comparable -
Float Float Float Float Float Double String Comparable -
Double Double Double Double Double Double String Comparable -
String String String String String String String Comparable -
Comparable Comparable Comparable Comparable Comparable Comparable Comparable Comparable -
Object - - - - - - - -

Literals

null, true, and false are the literals available in conditions. For example:

  • request.header.host is null
  • flow.cachehit is true

Examples

<RouteRule name="default">
     <Condition>request.header.content-type = "text/xml"</Condition>
     <TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>
<Step>
    <Condition>response.status.code = 503</Condition>
    <Name>MaintenancePolicy</Name>
</Step>
<Flow name="GetRequests">
    <Condition>response.verb="GET"</Condition>
    <Request>
        <Step>
            <Condition>request.path ~ "/statuses/**"</Condition>
            <Name>StatusesRequestPolicy</Name>
        </Step>
    </Request>
    <Response>
        <Step>
            <Condition>(response.status.code = 503) or (response.status.code = 400)</Condition>
            <Name>MaintenancePolicy</Name>
        </Step>
    </Response>
</Flow>

Help or comments?