Conditional Policy Execution
Conditions are part of policy configuration as explained on the What is Policy? page. Condition definitions are made from the conditions section when creating or editing a policy.
Conditional Policy Execution Concept
Conditional policy execution enables policies to be executed based on specific conditions. In Apinizer, conditions are created without writing code, using Variable and form-based configuration.
The following diagram shows how conditional policy execution occurs through the Gateway:
sequenceDiagram
participant Client as 👤 Client
participant Gateway as 🚪 API Gateway
participant Proxy as 🔀 API Proxy
participant Condition as 🔍 Condition Evaluation
participant Variables as 📊 Variables
participant Policy1 as 🛡️ Policy 1
participant Policy2 as 🛡️ Policy 2
participant Backend as 🖥️ Backend Service
Client->>Gateway: HTTP Request<br/>(Path, Headers, Query, Body)
Note over Gateway: Request Reached Gateway
Gateway->>Proxy: Route Request to API Proxy
Note over Proxy: API Proxy Processing Started
Proxy->>Condition: Conditional Policy<br/>Evaluation
Note over Condition: Condition Check
Condition->>Variables: Variable Values<br/>Extracted
Note over Variables: Variable Sources:<br/>Header, Query Param,<br/>Message Content (JSONPath/XPath),<br/>Context, System Variable
Variables->>Condition: Variable Values Returned
Condition->>Condition: Condition Evaluation<br/>(Operator: EQ, NE, GT, LT,<br/>CONTAINS, IN, etc.)
alt Condition 1 Met
Condition->>Policy1: Condition 1 Met<br/>Policy 1 Executed
Note over Policy1: Example: Content-Type == "application/json"<br/>→ JSON Schema Validation
Policy1->>Proxy: Policy 1 Completed
else Condition 2 Met
Condition->>Policy2: Condition 2 Met<br/>Policy 2 Executed
Note over Policy2: Example: Content-Type == "application/xml"<br/>→ XML Schema Validation
Policy2->>Proxy: Policy 2 Completed
else Condition Not Met
Condition->>Proxy: Condition Not Met<br/>Alternative Policy or<br/>Continue
end
Proxy->>Backend: Processed Request<br/>Forwarded to Backend
Backend->>Proxy: Response Returns
Note over Proxy: Post-flow Policies<br/>(Can be conditional)
Proxy->>Gateway: Processed Response
Gateway->>Client: HTTP Response
Note over Client,Gateway: Process Completed
Form-Based Condition Creation
When creating conditional policies, the following steps are followed:
You select the variable on the left side of the comparison. This variable can be:
- Header variable
- Query parameter variable
- Message content variable (with JSONPath/XPath)
- Context variable
- System variable
- Custom variable
You select the data type of the variable:
- STRING: For text comparisons
- NUMERIC: For numeric comparisons
- DATE: For date comparisons (date format must be specified)
You select the comparison operator from the dropdown menu:
- Comparison operators such as equality, greater than, less than
- Text operators such as contains, starts with, ends with
- Existence check operators such as exists, not exists, empty
You determine the source of the second value:
- Constant Value: A constant value entered directly
- Variable: Selection of another variable (variable-to-variable comparison)
You combine conditions with AND, OR, NOT operators by adding sub-conditions for complex logic.
This approach allows you to create conditional policies without writing code, by filling form fields and selecting Variables.
Condition Types and Variable Usage
Conditions are created using Variable. Variables can get values from message content, headers, query parameters, or context.
Message Content Conditions
To create conditions based on message content, variables are defined using JSONPath or XPath:
To extract values from JSON messages:
- Variable Type: Message Content (JSONPath)
- JSONPath Expression:
$.user.roleor$.products[*].price - Data Type: STRING or NUMERIC
To extract values from XML messages:
- Variable Type: Message Content (XPath)
- XPath Expression:
/user/roleor//product/@price - Data Type: STRING or NUMERIC
Based on HTTP header values:
- Variable Type: Header
- Header Name:
Content-TypeorX-API-Version - Data Type: STRING
Based on query parameters:
- Variable Type: Query Parameter
- Parameter Name:
versionorformat - Data Type: STRING
Client Conditions
To create conditions based on client information, relevant variables are used:
IP Address
For control based on IP address:
- Variable Type: Client IP
- Data Type: STRING
- Operator: IN or NOT_IN
- Value:
192.168.1.0/24#10.0.0.0/8(list values separated by #)
Used for IP whitelist/blacklist control.
User Agent
For control based on User-Agent header:
- Variable Type: Header
- Header Name:
User-Agent - Data Type: STRING
- Operator: CONTAINS or STARTS_WITH
Used for browser or mobile device control.
API Key
For control based on API Key value:
- Variable Type: Header
- Header Name:
X-API-KeyorAuthorization - Data Type: STRING
- Operator: EQ or IN
Different policies can be applied based on API Key type or value.
Context Values
For control based on user information in context:
- Variable Type: Context Variable
- Variable Name:
context.user.roleorcontext.user.id - Data Type: STRING
- Operator: EQ, IN, etc.
Used for authorization based on user role or identity information.
Time Conditions
System variables are used for time-based conditions:
- Variable Type: System Variable (date variable)
- Data Type: DATE
- Date Format:
yyyy-MM-dd(must be specified) - Operator: GE, LE, GT, LT
Used for access control within a specific date range.
- Variable Type: System Variable (time variable)
- Data Type: STRING or DATE (according to time format)
- Operator: GE, LE
Used for business hours control.
- Variable Type: System Variable (day variable)
- Data Type: STRING
- Operator: EQ or IN
Used for access control on specific days of the week.
- Variable Type: System Variable (timezone variable)
- Data Type: STRING
- Operator: EQ
Used for timezone-based control.
System and Environment Conditions
Conditions based on system and environment variables:
Environment Variable
For control based on environment variables:
- Variable Type: Environment Variable
- Variable Name:
ENVIRONMENTorFEATURE_FLAG - Data Type: STRING
- Operator: EQ, NE, etc.
Used for environment-based (development, test, production) control.
System Property
For control based on system properties:
- Variable Type: System Property
- Property Name:
app.versionorsystem.property - Data Type: STRING
- Operator: EQ, NE, etc.
Used for system version or feature control.
Cache Value
For control based on values in cache:
- Variable Type: Cache Variable
- Cache Key:
user.statusor cache key - Data Type: STRING
- Operator: EQ, IS_EXISTS, etc.
Used for dynamic control based on values in cache.
Condition Configuration
Conditions are created using Variable and form-based configuration. Each condition consists of the following components:
Condition Components
-
First Variable: Variable on the left side of the comparison
- Header variable
- Query parameter variable
- Message content variable (JSONPath/XPath)
- Context variable
- Custom variable
-
Data Type: Data type of the variable
- STRING: For text comparisons
- NUMERIC: For numeric comparisons
- DATE: For date comparisons (date format must be specified)
-
Comparison Operator: Type of comparison between two values
-
Second Value Source:
- Constant Value: A constant value entered directly
- Variable: Selection of another variable
-
Logical Operator: To combine multiple conditions
- AND: All conditions must be met
- OR: At least one condition must be met
- NOT: Condition must not be met
Comparison Operators
Comparison operators that can be used in conditions:
Text (STRING) Operators
| Operator | Description | Usage Scenario |
|---|---|---|
| Equals (EQ) | Variable exists and its value equals the given value | Content-Type == "application/json" |
| Not Equals (NE) | Variable does not exist, or its value does not equal the given value | version != "v1" |
| Equals - Ignore Case (EQ_IGNORE_CASE) | Variable exists and its value equals the given value (case insensitive) | contentType EQ_IGNORE_CASE "application/json" |
| Not Equals - Ignore Case (NE_IGNORE_CASE) | Variable does not exist, or its value does not equal the given value (case insensitive) | contentType NE_IGNORE_CASE "text/xml" |
| Less Than (LT) | Smaller in alphabetical order? | "apple" < "banana" |
| Less Than or Equal (LE) | Less than or equal? | "apple" <= "banana" |
| Greater Than (GT) | Larger in alphabetical order? | "zebra" > "apple" |
| Greater Than or Equal (GE) | Greater than or equal? | "zebra" >= "apple" |
| Contains (CONTAINS) | Variable exists and its value contains the given text | userAgent CONTAINS "Mobile" |
| Not Contains (NOT_CONTAINS) | Variable does not exist, or its value does not contain the given text | path NOT_CONTAINS "/admin" |
| Contains - Ignore Case (CONTAINS_IGNORE_CASE) | Variable exists and its value contains the given text (case insensitive) | userAgent CONTAINS_IGNORE_CASE "mobile" |
| Not Contains - Ignore Case (NOT_CONTAINS_IGNORE_CASE) | Variable does not exist, or its value does not contain the given text (case insensitive) | path NOT_CONTAINS_IGNORE_CASE "/admin" |
| Starts With (STARTS_WITH) | Variable exists and its value starts with the given text | path STARTS_WITH "/api/v2" |
| Not Starts With (NOT_STARTS_WITH) | Variable does not exist, or its value does not start with the given text | path NOT_STARTS_WITH "/internal" |
| Starts With - Ignore Case (STARTS_WITH_IGNORE_CASE) | Variable exists and its value starts with the given text (case insensitive) | path STARTS_WITH_IGNORE_CASE "/API" |
| Not Starts With - Ignore Case (NOT_STARTS_WITH_IGNORE_CASE) | Variable does not exist, or its value does not start with the given text (case insensitive) | path NOT_STARTS_WITH_IGNORE_CASE "/internal" |
| Ends With (ENDS_WITH) | Variable exists and its value ends with the given text | filename ENDS_WITH ".json" |
| Not Ends With (NOT_ENDS_WITH) | Variable does not exist, or its value does not end with the given text | filename NOT_ENDS_WITH ".xml" |
| Ends With - Ignore Case (ENDS_WITH_IGNORE_CASE) | Variable exists and its value ends with the given text (case insensitive) | filename ENDS_WITH_IGNORE_CASE ".JSON" |
| Not Ends With - Ignore Case (NOT_ENDS_WITH_IGNORE_CASE) | Variable does not exist, or its value does not end with the given text (case insensitive) | filename NOT_ENDS_WITH_IGNORE_CASE ".xml" |
| In (IN) | Variable exists and its value is in the given list | role IN ["admin", "user"] |
| Not In (NOT_IN) | Variable does not exist, or its value is not in the given list | status NOT_IN ["deleted", "archived"] |
| In - Ignore Case (IN_IGNORE_CASE) | Variable exists and its value is in the given list (case insensitive) | role IN_IGNORE_CASE ["Admin", "User"] |
| Not In - Ignore Case (NOT_IN_IGNORE_CASE) | Variable does not exist, or its value is not in the given list (case insensitive) | status NOT_IN_IGNORE_CASE ["Deleted"] |
Numeric (NUMERIC) Operators
| Operator | Description | Usage Scenario |
|---|---|---|
| Equals (EQ) | Are two numbers equal? | price == 100 |
| Not Equals (NE) | Are two numbers not equal? | count != 0 |
| Less Than (LT) | Is the first number less than the second? | age < 18 |
| Less Than or Equal (LE) | Less than or equal? | quantity <= 10 |
| Greater Than (GT) | Is the first number greater than the second? | score > 80 |
| Greater Than or Equal (GE) | Greater than or equal? | balance >= 1000 |
| In (IN) | Is it in the specified number list? | statusCode IN [200, 201, 204] |
| Not In (NOT_IN) | Is it not in the specified number list? | errorCode NOT_IN [404, 500] |
Date (DATE) Operators
Date format must be specified for date comparisons (e.g., yyyy-MM-dd, dd/MM/yyyy).
| Operator | Description | Usage Scenario |
|---|---|---|
| Equals (EQ) | Are two dates the same? | expiryDate == "2024-12-31" |
| Not Equals (NE) | Are two dates different? | startDate != "2024-01-01" |
| Less Than (LT) | Is the first date before the second? | createdDate < "2024-06-01" |
| Less Than or Equal (LE) | Before or the same? | deadline <= "2024-12-31" |
| Greater Than (GT) | Is the first date after the second? | expiryDate > "2024-01-01" |
| Greater Than or Equal (GE) | After or the same? | startDate >= "2024-01-01" |
Existence Check Operators
These operators do not require a second value, they only check the status of the variable:
| Operator | Description | Usage Scenario |
|---|---|---|
| Exists (IS_EXISTS) | Variable exists (regardless of its value) | apiKey IS_EXISTS |
| Not Exists (IS_NOT_EXISTS) | Variable does not exist | optionalHeader IS_NOT_EXISTS |
| Empty (IS_EMPTY) | Variable does not exist, or its value is empty | queryParam IS_EMPTY |
| Not Empty (IS_NOT_EMPTY) | Variable exists and its value is not empty | requestBody IS_NOT_EMPTY |
| Exists But Empty (EXISTS_AND_EMPTY) | Variable exists but its value is empty | header EXISTS_AND_EMPTY |
List Values: For IN and NOT_IN operators, list values are separated by # character. Example: admin#user#guest or 100#200#300
Null Value Handling
Null values are handled specially in conditions:
| Status | Operator | Result |
|---|---|---|
| First value null, second value null | EQ | true (null == null) |
| First value null, second value null | NE | false (null != null is not) |
| First value null, second value filled | EQ | false |
| First value null, second value filled | NE | true |
| First value filled, second value null | EQ | false |
| First value filled, second value null | NE | true |
| First value null | GT, LT, GE, LE, CONTAINS, IN, STARTS_WITH, ENDS_WITH, CONTAINS_IGNORE_CASE, IN_IGNORE_CASE, STARTS_WITH_IGNORE_CASE, ENDS_WITH_IGNORE_CASE, EQ_IGNORE_CASE | false |
| First value null | NOT_CONTAINS, NOT_IN, NOT_STARTS_WITH, NOT_ENDS_WITH, NOT_CONTAINS_IGNORE_CASE, NOT_IN_IGNORE_CASE, NOT_STARTS_WITH_IGNORE_CASE, NOT_ENDS_WITH_IGNORE_CASE, NE_IGNORE_CASE | true |
Use IS_EXISTS, IS_NOT_EXISTS, IS_EMPTY, IS_NOT_EMPTY operators for null value checking. These operators handle null values correctly.
Condition Creation Examples
The following examples show how conditions are created with the form-based approach:
Example 1: Content-Type Based Validation
Scenario: Different validation policies will be applied based on Content-Type header.
Form Configuration:
- First Variable: Header variable selected →
Content-Type - Data Type: STRING
- Operator: Equals (EQ)
- Second Value Source: Constant value
- Second Value:
application/json
Result: If Content-Type header is application/json, JSON Schema Validation Policy runs.
Alternative Conditions (nested conditions):
- Condition 1: If Content-Type is
application/xml→ XML Schema Validation Policy- First Variable: Header →
Content-Type - Operator: EQ
- Second Value:
application/xml
- First Variable: Header →
- Condition 2: Other cases → Reject Request (400 Bad Request)
- ELSE case
Example 2: API Version Based Routing
Scenario: Routing to different backends based on version value in query parameter.
Form Configuration:
- First Variable: Query Parameter variable selected →
version - Data Type: STRING
- Operator: Equals (EQ)
- Second Value Source: Constant value
- Second Value:
v1
Result: If query parameter version=v1, routed to Backend v1.
Alternative Conditions:
- Condition 1: If version is
v2→ Route to Backend v2- First Variable: Query Parameter →
version - Operator: EQ
- Second Value:
v2
- First Variable: Query Parameter →
- Condition 2: Other cases → Route to Default Backend
- ELSE case
Example 3: User Role Based Authorization
Scenario: Different policy will be applied based on user role.
Form Configuration:
- First Variable: Context Variable selected →
context.user.role - Data Type: STRING
- Operator: Equals (EQ)
- Second Value Source: Constant value
- Second Value:
admin
Result: If user role is admin, all operations are allowed.
Alternative Conditions:
- Condition 1: If role is
user→ Rate Limiting Policy (100 req/min)- First Variable: Context Variable →
context.user.role - Operator: EQ
- Second Value:
user
- First Variable: Context Variable →
- Condition 2: Other cases → Reject Request (403 Forbidden)
- ELSE case
Example 4: IP Based Rate Limiting
Scenario: Different rate limit values will be applied based on IP address.
Form Configuration:
- First Variable: Client IP variable selected
- Data Type: STRING
- Operator: In (IN)
- Second Value Source: Constant value
- Second Value:
192.168.1.0/24#10.0.0.0/8(list values separated by #)
Result: If IP address is in one of the specified ranges, Rate Limiting Policy (1000 req/min) is applied.
Alternative Condition:
- Condition 2: Other cases → Rate Limiting Policy (100 req/min)
- ELSE case
Example 5: Time-based Access Control (Nested Conditions)
Scenario: Access permission will be given during business hours.
Form Configuration (Nested conditions with AND logic):
- Logical Operator: AND selected
- First Sub-Condition:
- First Variable: System Variable →
current.time - Data Type: STRING or DATE (according to time format)
- Operator: Greater Than or Equal (GE)
- Second Value:
09:00
- First Variable: System Variable →
- Second Sub-Condition:
- First Variable: System Variable →
current.time - Data Type: STRING or DATE
- Operator: Less Than or Equal (LE)
- Second Value:
17:00
- First Variable: System Variable →
Result: If time is between 09:00-17:00, request is accepted, otherwise rejected (503 Service Unavailable).
Nested Conditions (Condition Combinations)
You can create nested conditions for complex logic. In the form-based approach, you combine conditions by adding sub-conditions:
AND Operator
Form Configuration:
- Logical Operator: AND selected
- First Sub-Condition:
- First Variable: Header →
Content-Type - Data Type: STRING
- Operator: Equals (EQ)
- Second Value:
application/json
- First Variable: Header →
- Second Sub-Condition:
- First Variable: Header →
X-API-Key - Data Type: STRING
- Operator: Equals (EQ)
- Second Value:
premium-key
- First Variable: Header →
Result: If both conditions are met, Premium JSON Processing Policy runs.
OR Operator
Form Configuration:
- Logical Operator: OR selected
- First Sub-Condition:
- First Variable: Client IP
- Data Type: STRING
- Operator: In (IN)
- Second Value:
192.168.1.0/24#10.0.0.0/8
- Second Sub-Condition:
- First Variable: Header →
X-API-Key - Data Type: STRING
- Operator: Equals (EQ)
- Second Value:
internal-key
- First Variable: Header →
Result: If one of the conditions is met, Internal Access Policy runs.
NOT Operator
Form Configuration:
- Logical Operator: NOT selected
- Sub-Condition:
- First Variable: Client IP
- Data Type: STRING
- Operator: In (IN)
- Second Value:
10.0.0.0/8
Result: If IP is not in the specified range, External Access Rate Limiting is applied.
Variable Comparison
In conditions, you can perform variable-to-variable comparison as well as comparisons with constant values:
Form Configuration:
- First Variable: Header →
Content-Type - Data Type: STRING
- Operator: Equals (EQ)
- Second Value Source: Variable selected
- Second Variable: Context Variable →
context.preferred.contentType
Result: If two variables are equal, policy runs. This approach is used for dynamic comparisons.
Conditional Policy Best Practices
- Use existing Variables, don't create unnecessary new variables
- Select variable types correctly (Header, Query Parameter, Message Content, Context Variable)
- Write and test JSONPath/XPath expressions correctly
- Use STRING for text comparisons
- Use NUMERIC for numeric comparisons
- Use DATE for date comparisons and specify date format
- Add most specific conditions first
- Leave general conditions last
- Always define ELSE case
- Use nested conditions for complex logic
- Select AND/OR/NOT operators correctly
- Keep condition depth reasonable (for readability)
- Use constant value option for constant values
- Use variable option for dynamic comparisons
- Ensure data types are compatible when doing variable-to-variable comparison
- Separate list values with
#character for IN and NOT_IN operators - Example:
admin#user#guestor100#200#300
- Use IS_EXISTS or IS_NOT_EXISTS to check variable existence
- Use IS_EMPTY or IS_NOT_EMPTY for empty value check
- These operators do not require a second value
- Check simple conditions first
- Leave heavy operations (JSONPath/XPath) last
- Consider cache usage
- Test all condition branches
- Test edge cases (empty values, null, etc.)
- Ensure variable values are available at runtime
- Understand how null values are handled