You're viewing Apigee Edge documentation.
Go to the
Apigee X documentation. info
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
.
Conditions overview
This section describes how and where to use conditional statements with Edge. In addition, the following sections describe the syntax:
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>
You can combine conditions with AND to enforce more than one at a time. For example, the
following conditions evaluate to true
only if the URI of the request matches
/statuses
and the HTTP verb of the request is
GET
:
<Condition>(proxy.pathsuffix MatchesPath "/statuses") and (request.verb = "GET")</Condition>
Where you can use conditional statements
You can use conditions to control behavior in the following:
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.
The following example conditionally transforms 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 Flow variables and 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
.
Variables
You can use both built-in flow variables and custom variables in conditional statements. For more information, see:
- Flow variables reference: A complete list of the built-in variables
- ExtractVariables policy: Instructions on setting custom variables
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
.
The following table lists the supported operators. You can use the symbol or the word in your expressions:
Symbol | Word | Description |
---|---|---|
! |
Not , not |
Unary operator (takes a single input) |
= |
Equals , Is |
Equals to (case sensitive) |
!= |
NotEquals , IsNot |
Not equals (case sensitive) |
:= |
EqualsCaseInsensitive |
Equals but is case insensitive |
> or > |
GreaterThan |
Greater than. If you use > when defining the condition in the Edge UI, it is converted to >. |
>= or >= |
GreaterThanOrEquals |
Greater than or equal to. If you use >= when defining the condition in the Edge UI, it is converted to >=. |
< |
LesserThan |
Lesser than. The Edge UI does not support the literal <. |
<= |
LesserThanOrEquals |
Lesser than or equal to. The Edge UI does not support the literal <=. |
&& |
And , and |
And |
|| |
Or |
The Or operator is not case sensitive. For example, OR , Or , and or are all valid. |
() |
Groups an expression. The ( opens the expression and ) closes
it. |
|
~~ |
JavaRegex |
Matches a |
~ |
Matches , Like |
Matches a glob-style pattern using the "*" wildcard character. The match is case-sensitive. For examples, see Pattern matching with conditionals. |
~/ |
MatchesPath , LikePath |
Matches a path expression. The match is case-sensitive. For examples, see Pattern matching with conditionals. |
=| |
StartsWith |
Matches the first characters of a string. The match is case-sensitive. |
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 adaptations shown in the following table (where RHS refers to the right side of the equation and LHS is the left side):
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 | - | - | - | - | - | - | - | - |
Null operands
The following table shows whether conditions evaluate to true
or
false
when values are null on the left-hand side (LHS) and/or right-hand side (RHS)
of the operand shown:
Operator | LHS null | RHS null | LHS and RHS null |
---|---|---|---|
= , == , := |
false | false | true |
=| |
false | false | false |
!= |
true | true | false |
> or > |
true | false | false |
>= or >= |
false | true | true |
< |
true | false | false |
<= |
true | false | true |
~ |
false | N/A | false |
~~ |
false | N/A | false |
!~ |
true | false | false |
~/ |
false | N/A | false |
Literals
In addition to string and numeric literals, you can use the following literals in conditional statements:
null
true
false
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>