This page applies to Apigee and Apigee hybrid.
View Apigee Edge documentation.
Conditions enable API proxies to behave dynamically at runtime. Conditions define operations
on variables, which are evaluated by the Apigee 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 Apigee. 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 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 Apigee UI, it is converted to >. |
>= or >= |
GreaterThanOrEquals |
Greater than or equal to. If you use >= when defining the condition in the Apigee UI, it is converted to >=. |
< |
LesserThan |
Lesser than. The Apigee UI does not support the literal <. |
<= |
LesserThanOrEquals |
Lesser than or equal to. The Apigee 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. |
~/ |
MatchesPath , LikePath |
Matches a path expression. The match is case-sensitive. For examples, see Pattern matching. |
=| |
StartsWith |
Matches the first characters of a string. The match is case-sensitive. |
Operands
Apigee 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
orF
(float
, for example,3.142f, 91.1F
)d
orD
(double
, for example,3.142d, 100.123D
)l
orL
(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>