Ana içeriğe geç

Script

ipucu

This document explains the detailed usage of a specific policy. If you are using the Apinizer policy structure for the first time or want to learn about the general working principles of policies, we recommend reading the What is a Policy? page first.

Overview

What is its Purpose?

  • Script Policy aims to solve integration requirements without writing code by applying custom business rules and data transformations in the API Proxy request pipeline.
  • Script Policy enables centralized management of operations such as masking, enriching incoming data, or adapting error messages in the response pipeline.
  • Script Policy makes it possible to create a global/local shared script library for consistent behavior across different environments.
  • Script Policy activates only for specific endpoint or header combinations through its condition engine, maintaining performance.

Working Principle

  1. Request Arrival: For every HTTP/HTTPS request arriving at the API Gateway, the source IP address of the request is detected.
  2. Policy Check: If Script Policy is active, the system checks in the following order:
    • Is a Condition defined? If so, is the condition met?
    • Is the policy active (active=true)?
    • Is a Variable being used or Apinizer default?
  3. Script Engine Execution: According to the selected executionType (SYNC/ASYNC) and scriptLanguage (Groovy/Javascript) values, the script runs in the specified pipeline region; request/response body, headers, and parameter maps can be updated.
  4. Decision Making:
    • Match Found: Message components updated as a result of the script are written back to the pipeline; in case of error, the defined statusCode and message are returned.
    • No Match: Script is skipped, request/response continues to default flow.
  5. Error Handling: Customizable HTTP status code and error message are returned for requests that do not comply with policy rules.

Features and Capabilities

Core Features

  • ExecutionType Management (Sync/Async): Determines whether the script will run synchronously or in the background; asynchronous mode does not block the endpoint during long-running operations.
  • Dual Script Language Support: Allows teams to use the language they are proficient in by choosing between Groovy and Javascript.
  • Context Variable Library: Provides ready-made variable maps for From Client, To Backend, From Backend, and To Client flows; readable/writable fields are clearly separated.
  • Active/Passive Status Control: Easily switch the policy's active or passive state (active/passive toggle). Policy is not applied when passive, but configuration is retained.
  • Condition-Based Application: Create complex conditions with Query Builder to determine when the policy will be applied (e.g., only for specific endpoints or header values).

Advanced Features

  • Script Test Laboratory: Run scripts with sample header/param/body data for different pipeline segments using the integrated test window and examine results.
  • Dependency Tracking: See which API Proxy or groups the policy is used in through Used Proxies/Policy Groups sections and perform change impact analysis.
  • Dynamic Context Value Selection: Automatically copy date, environment, or proxy metadata information from EnumScriptContextValue for use within scripts.
  • Export/Import Feature: Export policy configuration as a ZIP file. Import to different environments (Development, Test, Production). Version control and backup capability.
  • Policy Group and Proxy Group Support: Manage multiple policies within Policy Groups. Assign policies in bulk to Proxy Groups. Centralized update and deploy operations.
  • Deploy and Versioning: Deploy policy changes to production environment. View which API Proxies use it (Policy Usage). Proxy Group and Policy Group usage reports.

Usage Scenarios

ScenarioSituationSolution (Policy Application)Expected Behavior / Result
Request Header InjectionExternal system requests additional headerHeader is added via requestHeaderMapToTargetAPI in From Client → To Backend scriptBackend call is made with required header
Sensitive Field MaskingResponse contains ID numberSensitive field is masked with regex in To Client scriptMasked data is returned to client
Dynamic Endpoint RoutingSome customers need to be routed to different backend URLScript sets requestBackendUrlToTargetAPI field conditionallyRequest is routed to appropriate target service
Conditional Error ReturnAccess must be blocked for specific API keysScript sets responseErrorMessageToClient and statusCodeToClient=403Client receives 403 and customized message
JWT EnrichmentNeed to generate context based on JWT claim valueScript reads claim and writes to customVariableMapSubsequent policies use enriched value

Configuring Policy Parameters

At this step, users can create a new policy or configure existing policy parameters to define access rules.

Creating New Script Policy

Script Policy

Configuration Steps

Step 1: Navigate to Creation Page

Go to Development → Global Settings → Global Policies → Script Policy from the left menu and click the [+ Create] button in the upper right.

Step 2: Enter Basic Information

Policy Status: Shows Active/Passive status. New policies are active by default.

Name - Required: Enter unique name (example: Production_ScriptPolicy). System checks automatically. Green check: available, Red cross: existing name.

Description: Explain the policy's purpose (Max. 1000 characters). Example: "Adds campaign header in request pipeline."

Step 3: Variable Usage

  • In the action button area at the top of the page, you can use the [<> Variable] button to select dynamic values.
  • Using context/global variable expressions, you can manage policy parameters with variable-based values instead of fixed values.
  • This reduces manual update effort when values change and provides operational convenience.
  • For detailed information, review Dynamic Variables.

Step 4: ExecutionType Selection

Select Sync or Async in Execution Type section:

  • When Sync is selected, script runs synchronously in gateway pipeline
  • Async triggers side channel to avoid blocking client during long operations

Step 5: Script Language Configuration

Select Javascript or Groovy under Script Language. Selection determines code editor syntax and IntelliSense.

Step 6: Script Body and Variable Management

  • Write or paste your script in the code editor
  • Copy fields like requestHeaderMapToTargetAPI, responseBodyTextToClient from variable tags with one click
  • You can transfer data to other policies via customVariableMap
  • Open test dialog with Try It button and run script with sample inputs

Step 7: Define Condition (Optional)

Switch to Condition tab. Conditions determine when the policy will be active.

Examples:

  • Environment-based: Header = X-Environment, Operator = Equals, Value = production
  • API Key-based: Header = X-API-Key, Starts With = PROD-
  • Endpoint-based: Path = /api/admin/*

If no condition is defined, policy is always active.

For details see: Conditions

Step 8: Error Message Customization (Optional)

Go to Error Message Customization tab and customize the message to be returned when access is denied.

Default:

{ "statusCode": 403, "message": "[Default error message]" }

Custom:

{ "statusCode": 403, "errorCode": "[CUSTOM_ERROR_CODE]", "message": "[Custom message]" }

Step 9: Save

Click [Save] button in upper right.

Checklist:

  • Unique name
  • Required fields filled
  • At least one script body line present

Result:

  • Policy is added to list
  • Can be connected to APIs
  • Automatically applied if global policy

For explanation of Conditions and Error Message Customization panels, see Conditions and Error Message Customization sections on the What is a Policy? page.

For a complete guide on all layers, priority order and scenario examples of the error message configuration system, see the Error Message Configuration Guide page.

Flow Variables

Flow variables and properties that you can use within Script Policy are explained in detail in the tables below.

Request Variables (Client → Apinizer)

Variable NamePipelineDirectionTypeAccessDescriptionExample Usage
requestHeaderMapFromClientRequestClient → ApinizerMap<String, String>ReadUsed to access header values of the original version when the request from client reaches Apinizer.String value= requestHeaderMapFromClient.get("Content-Type");
requestUrlParamMapFromClientRequestClient → ApinizerMap<String, String>ReadUsed to access query parameter values of the original version when the request from client reaches Apinizer.String value= requestUrlParamMapFromClient.get("param");
requestBodyTextFromClientRequestClient → ApinizerStringReadUsed to access body value of the original version when the request from client reaches Apinizer.String value= requestBodyTextFromClient;
requestUrlFromClientRequestClient → ApinizerStringReadContains the endpoint path the incoming request was matched to (e.g. /pet/findByStatus). For SOAP type API Proxies, the value of this variable is the SOAP method name.String value= requestUrlFromClient;
requestFormUrlEncodedListFromClientRequestClient → ApinizerList<BasicNameValuePair>ReadUsed to access "Form-URL-Encoded" parameters of the original version when the request from client reaches Apinizer.See Form URL-Encoded Usage section for detailed example.
requestFormDataListFromClientRequestClient → ApinizerList<ApinizerRequestBodyPart>ReadUsed to access "Form-Data" parameters of the original version when the request from client reaches Apinizer.See Form Data Usage section for detailed example.

Request Variables (Apinizer → Backend API)

Variable NamePipelineDirectionTypeAccessDescriptionExample Usage
requestHeaderMapToTargetAPIRequestApinizer → Backend APIMap<String, String>Read, WriteUsed to access header values of the request going from Apinizer to Backend API. Values in this field contain changes made in the request pipeline and may differ from the original request reaching Apinizer.String value= requestHeaderMapToTargetAPI.get("Content-Type");

requestHeaderMapToTargetAPI.put("Content-Type","application/json");
requestUrlParamMapToTargetAPIRequestApinizer → Backend APIMap<String, String>Read, WriteUsed to access query parameter values of the request going from Apinizer to Backend API. Values in this field contain changes made in the request pipeline and may differ from the original request reaching Apinizer.String value= requestUrlParamMapToTargetAPI.get("param");

requestHeaderMapToTargetAPI.put("param","value");
requestBodyTextToTargetAPIRequestApinizer → Backend APIStringRead, WriteUsed to access body value of the request going from Apinizer to Backend API. Value in this field contains changes made in the request pipeline and may differ from the original request reaching Apinizer.String value= requestBodyTextToTargetAPI;

requestBodyTextToTargetAPI= "<body>";
requestFormUrlEncodedListToTargetAPIRequestApinizer → Backend APIList<BasicNameValuePair>Read, WriteUsed to access "Form-Url Encoded" parameter values of the request going from Apinizer to Backend API. Values in this field contain changes made in the request pipeline and may differ from the original request reaching Apinizer.See Form URL-Encoded Usage section for detailed example.
requestFormDataListToTargetAPIRequestApinizer → Backend APIList<ApinizerRequestBodyPart>Read, WriteUsed to access "Form-Data" parameter values of the request going from Apinizer to Backend API. Values in this field contain changes made in the request pipeline and may differ from the original request reaching Apinizer.See Form Data Usage section for detailed example.
requestErrorMessageToTargetAPIRequestApinizer → Backend APIStringWriteIf you want to interrupt the flow in the request pipeline and return a message to the client, enter the message to be returned in this variable. If this message has a value after script execution, the flow is interrupted and this value is returned to the client.requestErrorMessageToTargetAPI= "<body>";
statusCodeToTargetAPIRequestApinizer → Backend APIIntegerWriteIf you want to interrupt the flow in the request pipeline and return a message to the client, enter the status code to be returned in this variable. Entering this value alone is not sufficient to stop the flow; requestErrorMessageToTargetAPI value must also be filled for the flow to stop.statusCodeToTargetAPI=500;
requestBackendUrlToTargetAPIRequestApinizer → Backend APIStringWriteThis field can be used if you want to change the context path of the Backend API URL. The default value of this variable is empty, and if a value is set to this variable, the target context path is changed with this value. To make requestBackendUrlToTargetAPI value empty, #EMPTY# value must be entered. When this value is used, the request is routed directly to the routing address without adding any path or query.See Backend URL Modification section for detailed examples.

Response Variables (Backend API → Apinizer)

Variable NamePipelineDirectionTypeAccessDescriptionExample Usage
responseHeaderMapFromTargetAPIResponseBackend API → ApinizerMap<String, String>ReadUsed to access header values of the original version when the result from Backend API reaches Apinizer.String value= responseHeaderMapFromTargetAPI.get("Content-Type");
responseBodyTextFromTargetAPIResponseBackend API → ApinizerStringReadUsed to access body value of the original version when the result from Backend API reaches Apinizer.String value= responseBodyTextFromTargetAPI;
statusCodeFromTargetAPIResponseBackend API → ApinizerIntegerReadUsed to access status code value of the original version when the result from Backend API reaches Apinizer.int value=statusCodeFromTargetAPI;

Response Variables (Apinizer → Client)

Variable NamePipelineDirectionTypeAccessDescriptionExample Usage
responseHeaderMapToClientResponseApinizer → ClientMap<String, String>Read, WriteUsed to access header values of the response returning from Apinizer to Client. Values in this field contain changes made in the response pipeline and may differ from the original response returning to Apinizer.String value= responseHeaderMapToClient.get("Content-Type");

responseHeaderMapToClient.put("Content-Type","application/json");
responseBodyTextToClientResponseApinizer → ClientStringRead, WriteUsed to access body value of the response returning from Apinizer to Client. Value in this field contains changes made in the response pipeline and may differ from the original response returning to Apinizer.String value= responseBodyTextToClient;

responseBodyTextToClient= "<body>";
responseErrorMessageToClientResponseApinizer → ClientStringRead, WriteIf you want to interrupt the flow in the response pipeline and return a message to the client, enter the message to be returned in this variable. If this message has a value after script execution, the flow is interrupted and this value is returned to the client.responseErrorMessageToClient= "<body>";
statusCodeToClientResponseApinizer → ClientIntegerRead, WriteIf you want to interrupt the flow in the response pipeline and return a message to the client, enter the status code to be returned in this variable. Entering this value alone is not sufficient to stop the flow; responseErrorMessageToClient value must also be filled for the flow to stop.int value=statusCodeToClient;

statusCodeToClient=401;
stopFlowAsSuccessRequest / ResponseScript → ApinizerbooleanWriteMarks the result as successful when the flow is interrupted and a message is returned to the client. When set to true, the request appears with resultType=SUCCESS in the traffic logs, is not counted in error/blocked analytics, and returns HTTP 200 if no status code was written (the default behavior would return 401). Status code exception: if the backend service returned 4xx/5xx on the response pipeline, that status code is preserved and is not converted to 200 — only the result type becomes SUCCESS. To mask the backend's error code as well, explicitly write the code you want to return to statusCodeToClient; a status code written by the script always takes precedence. This variable does not stop the flow on its own — responseErrorMessageToClient (response pipeline) or requestErrorMessageToTargetAPI (request pipeline) must still be filled for the flow to stop. When it is not set, behavior is unchanged and the result is marked as BLOCKED.responseErrorMessageToClient= "{\"status\":\"ok\"}";

stopFlowAsSuccess= true;

Detailed Usage Examples

Form URL-Encoded Usage

import org.apache.http.message.BasicNameValuePair

String selectedValue;
for (BasicNameValuePair nameValuePair : requestFormUrlEncodedListFromClient) {
if("test".equals(nameValuePair.getName())){
selectedValue=nameValuePair.getValue();
}
}

Form Data Usage

import com.apinizer.common.global.apinizerrequest.*;

for (ApinizerRequestBodyPart bodyPart : requestFormDataListFromClient) {
if(bodyPart.getBodyPartType().isText()){
ApinizerRequestTextBody textBodyPart = ((ApinizerRequestTextBody)bodyPart));
String text=textBodyPart.getText();
//do some logic
}else{//bodyPart.getBodyPartType().isBinary()
ApinizerRequestBinaryBody binaryBodyPart = ((ApinizerRequestBinaryBody)bodyPart));
byte[] byteArr=binaryBodyPart.getContent();
String fileName=binaryBodyPart.getFileName();
//do some logic
}
}

Backend URL Modification

Example Scenario:

Current routing address: "https://apinizer.com/api"

Incoming request context path: "/findByStatus?param=value"

In this case, the request goes to: "https://apinizer.com/api/findByStatus?param=value"

When the following code is written:

requestBackendUrlToTargetAPI="/new/path/value?p=v";

The request goes to: "https://apinizer.com/api/new/path/value?p=v"

When the following code is written:

requestBackendUrlToTargetAPI="#EMPTY#"

The request goes to: "https://apinizer.com/api"

Accessing Environment Variables

The ${variable} placeholder syntax is not resolved inside the script body (Groovy interprets it as a GString, JavaScript as a template literal). To access environment variables from within a script, use environmentVariableMap.

String dbHost = environmentVariableMap.get("dbHost");
String apiKey = environmentVariableMap.get("apiKey");

if (environmentVariableMap.containsKey("featureFlag")) {
// variable is defined, use it
}
not

Behavior:

  • The map is read-only; put, remove, and clear calls throw UnsupportedOperationException.
  • Iteration is supported: keySet(), values(), entrySet() let you discover all variable names/values in the active environment.
  • Operates against the active environment; a fresh snapshot is built for each script execution.
  • Values marked as Secret are returned in their resolved (plain) form.
  • Keys are case-insensitive: get("dbHost"), get("DBHOST"), get("dbhost") all return the same value.
// Discovery example — log every variable in the active environment
environmentVariableMap.keySet().each { name ->
request_log("env: " + name + " = " + environmentVariableMap.get(name));
}

Accessing Credential Information

The existing credential_* variables return only the authenticated credential of the request. To access another credential by its username or client ID, use credentialMap.

Example 1 — Basic Auth header (resolved password)

def cred = credentialMap.get("acme-app");
if (cred != null) {
String token = cred.getUsername() + ":" + cred.getResolvedPassword();
String header = "Basic " + Base64.getEncoder().encodeToString(token.getBytes());
requestHeaderMapToTargetAPI.put("Authorization", header);
}

Example 2 — JWT signing (private key)

def cred = credentialMap.get("jwt-signer");
java.security.PrivateKey privateKey = cred?.getPrivateKey();
// sign JWT with privateKey...

Example 3 — Loading a keystore for mTLS

def cred = credentialMap.get("backend-mtls");
java.security.KeyStore ks = cred?.getKeyStore();
// bind ks into SSLContext...

Example 4 — JWK for JWE decryption

def cred = credentialMap.get("jwe-recipient");
def jwk = cred?.getJwkForDecryptionAndEncryption();
// decrypt with jwk...

Example 5 — The authenticated user's credential

def me = credentialMap.get(request_usernameOrKey);
String myEmail = me?.getEmail();
String myOrg = me?.getOrganizationName();

Example 6 — Reading custom metadata

def cred = credentialMap.get("acme-app");
Map<String, String> meta = cred?.getMetadata();
String tenantId = meta?.get("tenant_id");
String department = meta?.get("department");
not

Accessible fields (on the object returned by credentialMap.get(...)):

  • Basic: getUsername(), getEmail(), getFullName(), getDescription()
  • Password: getResolvedPassword() (decrypted; if the password value contains a ${variable} placeholder, it is substituted), getEnvironmentPassword("environment-id") (resolved environment-scoped password)
  • Identity metadata: getOrganizationId(), getOrganizationName(), getProjectId(), getProjectName(), getAppId(), getAppName()
  • Authorization and status: getRoleNameList(), getEnabled(), isExternal(), getExpireDate(), getGrantType()
  • Key material: getSecretKey(), getCertificate(), getPublicKey(), getPrivateKey(), getKeyStore(), getTrustStore(), getJwkForValidationAndSign(), getJwkForDecryptionAndEncryption()
  • Key identifiers: getSecretKeyId(), getCertificateId(), getPublicKeyId(), getPrivateKeyId(), getKeyStoreId(), getTrustStoreId()
  • Custom metadata (the key/value pairs defined on the credential and on its organization): getMetadata() (organization + credential entries merged, credential overrides on key collision; values are resolved and decrypted), getCredentialMetadata() (credential level only), getOrganizationMetadata() (organization level only) — each returns a read-only Map<String, String>
uyarı

Null check: credentialMap.get("...") returns null when the credential cannot be found. Calling a getter on a null reference raises an error — use Groovy's ?. operator or an explicit if (cred != null) check.

Key enumeration is disabled: credentialMap.keySet(), values(), and entrySet() calls raise an error. Only lookup by a known username or client ID is supported.

Security: Granting permission to create script policies effectively grants access to the resolved password and key material of every credential through this method. Ensure that the user is also authorized to view the relevant credentials.

Important Notes

not

If Script type is Groovy:

  • JsonSlurper for JSON message body,
  • XMLSlurper for XML message body

Using these makes message processing much easier.

uyarı

When the request is blocked with error message variables, the error message returned to the client is whatever is written to this variable's value instead of the Error Message Template.

Message Variables

Message variables and properties that you can use within Script Policy are explained in detail in the tables below.

Request Pipeline Variables

Flow VariablesValue LocationData TypeAllowed OperationDescriptionExample Usage
request_remoteAddressClient → ApinizerStringRead, WriteUsed to access "Remote Address" value in the request from client.String value= request_remoteAddress;

request_remoteAddress= "<new value>";
request_httpMethodClient → ApinizerStringRead, WriteUsed to access "HTTP Method" value in the request from client.String value= request_httpMethod;

request_httpMethod= "<new value>";
request_contentTypeClient → ApinizerStringRead, WriteUsed to access "Content Type" value in the request from client.String value= request_contentType;

request_contentType= "<new value>";
request_pathInfoClient → ApinizerStringRead, WriteUsed to access "Path Info" value in the request from client.String value=request_pathInfo ;

request_pathInfo= "<new value>";
request_contextPathClient → ApinizerStringRead, WriteUsed to access "Context Path" value in the request from client.String value= request_contextPath;

request_contextPath= "<new value>";
request_queryStringClient → ApinizerStringRead, WriteUsed to access "Query String" value in the request from client.String value= request_queryString;

request_queryString= "<new value>";
request_remoteUserClient → ApinizerStringRead, WriteUsed to access "Remote User" value in the request from client.String value= request_remoteUser;

request_remoteUser= "<new value>";
request_usernameOrKeyClient → ApinizerStringRead, WriteUsed to access "Username or API Key" value in the request from client. If the request is authenticated by a security policy on Apinizer, this value is assigned by Apinizer, or a value can be assigned manually with data manipulation policies.String value= request_usernameOrKey;

request_usernameOrKey= "<new value>";
request_requestedSessionIdClient → ApinizerStringRead, WriteUsed to access "Requested Session Id" value in the request from client.String value= request_requestedSessionId;

request_requestedSessionId= "<new value>";
request_requestURIClient → ApinizerStringRead, WriteUsed to access "Request URI" value in the request from client.String value= request_requestURI;

request_requestURI= "<new value>";
request_characterEncodingClient → ApinizerStringRead, WriteUsed to access "Character Encoding" value in the request from client.String value= request_characterEncoding;

request_characterEncoding= "<new value>";
request_charsetClient → ApinizerStringRead, WriteUsed to access "Charset" value in the request from client.String value= request_charset;

request_charset= "<new value>";
request_contentLengthClient → ApinizerStringRead, WriteUsed to access "Content Length" value in the request from client.String value= request_contentLength;

request_contentLength= "<new value>";
request_protocolClient → ApinizerStringRead, WriteUsed to access "Protocol" value in the request from client.String value= request_protocol;

request_protocol= "<new value>";
request_schemeClient → ApinizerStringRead, WriteUsed to access "Scheme" value in the request from client.String value= request_scheme;

request_scheme= "<new value>";
request_serverNameClient → ApinizerStringRead, WriteUsed to access "Server Name" value in the request from client.String value= request_serverName;

request_serverName= "<new value>";
request_serverPortClient → ApinizerStringRead, WriteUsed to access "Server Port" value in the request from client.String value= request_serverPort;

request_serverPort= "<new value>";
request_remoteHostClient → ApinizerStringRead, WriteUsed to access "Remote Host" value in the request from client.String value= request_remoteHost;

request_remoteHost = "<new value>";
request_remotePortClient → ApinizerStringRead, WriteUsed to access "Remote Port" value in the request from client.String value= request_remotePort;

request_remotePort= "<new value>";
request_localNameClient → ApinizerStringRead, WriteUsed to access "Local Name" value in the request from client.String value= request_localName;

request_localName= "<new value>";
request_localAddrClient → ApinizerStringRead, WriteUsed to access "Local Address" value in the request from client.String value= request_localAddr;

request_localAddr= "<new value>";
request_localPortClient → ApinizerStringRead, WriteUsed to access "Local Port" value in the request from client.String value= request_localPort;

request_localPort= "<new value>";
request_xForwardedForClient → ApinizerStringRead, WriteUsed to access "X-Forwarded-For" value in the request from client.String value= request_xForwardedFor;

request_xForwardedFor= "<new value>";
request_isSoapToRestClient → ApinizerbooleanReadInformation about whether the request goes to an API Proxy with SoapToRest conversion after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_isSoapToRest;
request_isApiProxyClient → ApinizerbooleanReadInformation about whether the request reaches API Proxy after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_isApiProxy;
request_isApiProxyGroupClient → ApinizerbooleanReadInformation about whether the request reaches an API Proxy Group after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_isApiProxyGroup;
request_data_isXwwwFormUrlEncodedClient → ApinizerbooleanRead, WriteInformation about whether the request contains application/x-www-form-urlencoded header after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_data_isXwwwFormUrlEncoded;

request_data_isXwwwFormUrlEncoded= true/false;
request_data_isFormDataClient → ApinizerbooleanRead, WriteInformation about whether the request contains "form data" after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_data_isFormData;

request_data_isFormData= true/false;
request_data_isByteArrayClient → ApinizerbooleanRead, WriteInformation about whether the request contains "byte array" data after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_data_isByteArray;

request_data_isByteArray= true/false;
request_data_hasAttachmentClient → ApinizerbooleanRead, WriteInformation about whether the request contains "attachment" data after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_data_hasAttachment;

request_data_hasAttachment= true/false;
request_encoding_gzipClient → ApinizerbooleanRead, WriteInformation about whether the request data format is "gzip" after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_encoding_gzip;

request_encoding_gzip= true/false;
request_encoding_deflateClient → ApinizerbooleanRead, WriteInformation about whether the request data format is "deflate" after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= request_encoding_deflate;

request_encoding_deflate= true/false;
request_encoding_brClient → ApinizerbooleanRead, WriteInformation about whether the request data format is "br" after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value = request_encoding_br;
request_encoding_br = true/false;
request_encoding_zstdClient → ApinizerbooleanRead, WriteInformation about whether the request data format is "zstd" after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value = request_encoding_zstd;
request_encoding_zstd = true/false;
request_encoding_identityClient → ApinizerbooleanRead, WriteInformation about whether the request data format is "identity" after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value = request_encoding_identity;
request_encoding_identity= true/false;
request_encoding_compressClient → ApinizerbooleanRead, WriteInformation about whether the request data format is "compress" after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value = request_encoding_compress;
request_encoding_compress= true/false;
request_httpServletClient → Apinizerjakarta.servlet.http.HttpServletRequestReadProvides access to the low-level servlet object of the request. Use it only for advanced scenarios that cannot be solved with the standard variables; incorrect use can break the request flow.def req= request_httpServlet;

Response Pipeline Variables

Flow VariablesValue LocationData TypeAllowed OperationDescriptionExample Usage
response_data_isByteArrayBackend API → ApinizerbooleanRead, WriteInformation about whether the response contains "byte array" data after being interpreted in Apinizer. This variable's value can be "true" or "false".boolean value= response_data_isByteArray;

response_data_isByteArray= true/false;
response_encoding_gzipBackend API → ApinizerbooleanRead, WriteInformation about whether the response data format is "gzip" after being interpreted in Apinizer. This variable's value can be "true" or "false". If the value is false and set to true in the script, the data returned to the client is compressed in gzip format.boolean value= response_encoding_gzip;

response_encoding_gzip= true/false;
response_encoding_deflateBackend API → ApinizerbooleanRead, WriteInformation about whether the response data format is "deflate" after being interpreted in Apinizer. This variable's value can be "true" or "false". If the value is false and set to true in the script, the data returned to the client is compressed in deflate format.boolean value= response_encoding_deflate;

response_encoding_deflate= true/false;
response_encoding_brBackend API → ApinizerbooleanRead, WriteInformation about whether the response data format is "br" after being interpreted in Apinizer. This variable's value can be "true" or "false". If the value is false and set to true in the script, the data returned to the client is compressed in br format.boolean value= response_encoding_br;

response_encoding_br= true/false;
response_encoding_compressBackend API → ApinizerbooleanRead, WriteInformation about whether the response data format is "compress" after being interpreted in Apinizer. This variable's value can be "true" or "false". If the value is false and set to true in the script, the data returned to the client is compressed in compress format.boolean value= response_encoding_compress;

response_encoding_compress= true/false;
response_encoding_zstdBackend API → ApinizerbooleanRead, WriteInformation about whether the response data format is "zstd" after being interpreted in Apinizer. This variable's value can be "true" or "false". If the value is false and set to true in the script, the data returned to the client is compressed in zstd format.boolean value= response_encoding_zstd;

response_encoding_zstd= true/false;
response_encoding_identityBackend API → ApinizerbooleanRead, WriteInformation about whether the response data format is "identity" after being interpreted in Apinizer. This variable's value can be "true" or "false". If the value is false and set to true in the script, the data returned to the client is returned in identity format.boolean value= response_encoding_identity;

response_encoding_identity= true/false;
response_charsetBackend API → ApinizerStringRead, WriteUsed to access and change the character set (charset) of the response from Backend API.String value= response_charset;

response_charset= "UTF-8";
response_backendContentEncodingBackend API → ApinizerStringRead, WriteUsed to access and change the original Content-Encoding header value of the response from Backend API.String value= response_backendContentEncoding;

response_backendContentEncoding= "gzip";
response_statusCodeBackend API → ApinizerIntegerRead, WriteContains the status code value of the response from Backend API.Integer value= response_statusCode;

response_statusCode= 400;
response_httpServletBackend API → Apinizerjakarta.servlet.http.HttpServletResponseReadProvides access to the low-level servlet object of the response. Use it only for advanced scenarios that cannot be solved with the standard variables; incorrect use can break the response flow.def resp= response_httpServlet;

Error Pipeline Variables

A Script policy added to the API Proxy's Error Pipeline can access error information through read-only variables, so it can branch based on the type of error that occurred. These variables are populated only in Script policies on the error pipeline; when no error occurred on the request or response pipeline, their values are empty (null).

Flow VariablesValue LocationData TypeAllowed OperationDescriptionExample Usage
error_categoryError Pipeline → ScriptStringReadThe coarse class of the error and the primary key for branching. Possible values: ROUTING_ERROR (backend routing failure), POLICY_BLOCK (a policy blocked the request), POLICY_ERROR (an error occurred while a policy was running), GATEWAY_ERROR (gateway/internal error).if (error_category == "ROUTING_ERROR") { ... }
error_typeError Pipeline → ScriptStringReadThe detailed type of the error; used when finer branching than error_category is needed.String value= error_type;
error_parentError Pipeline → ScriptStringReadThe parent group the error belongs to.String value= error_parent;
error_resultTypeError Pipeline → ScriptStringReadThe result type: BLOCKED (request was blocked) or ERROR (an error occurred).String value= error_resultType;
error_messageError Pipeline → ScriptStringReadThe error's description/detail message.String value= error_message;
error_codeError Pipeline → ScriptStringReadThe error code.String value= error_code;
error_httpCodeError Pipeline → ScriptIntegerReadThe HTTP status code corresponding to the error.Integer value= error_httpCode;
not

Error pipeline variables are read-only; they are assigned by the system when an error is caught and the Script only reads them. Assigning a value to these variables does not change the system's error response. To change the body, headers, or status code of the error response, use the response pipeline variables (responseBodyTextToClient, responseHeaderMapToClient, statusCodeToClient).

Example — transforming the response based on the error type:

import groovy.json.JsonOutput

if (error_category == "ROUTING_ERROR") {
// Return a simple, consistent message to the client when the backend is unreachable
responseBodyTextToClient = JsonOutput.toJson([
status : "unavailable",
reason : error_type,
code : error_code,
detail : error_message
])
statusCodeToClient = 503
} else {
// POLICY_BLOCK / POLICY_ERROR / GATEWAY_ERROR: the response is left untouched and the error is returned as is
}

Behavior of Encoding Variables and Routing Settings

In the script policy, the data format variables (gzip, deflate, br, zstd, compress, identity) on the request or response pipeline can be written. These variables work in combination with the encoding override settings in the routing configuration, and the precedence between them is important.

Execution Order

A request's data flow goes through the following steps:

  1. Client-side headers are read — The data format header sent by the client is evaluated.
  2. Routing override settings are applied — Encoding override values defined on the API Proxy or Routing override the client-supplied header.
  3. Body is decompressed — The compressed request body is decompressed according to the resolved settings.
  4. Backend-side compression override is applied — The format to be used when forwarding to the backend is determined.
  5. Request pipeline policies run — The script policy kicks in at this stage. If an encoding variable is written inside the script, it overrides all previous settings.
  6. Body is forwarded to the backend — Compression is applied based on the final value left by the script.

The response pipeline works the same way; routing settings are applied first to the backend response, and the response pipeline script policy has the final say.

uyarı

When an encoding variable is written inside the script, the override values defined in the routing settings are silently overridden. If the script policy and routing settings are used together on the same API Proxy, the order of precedence must be planned deliberately.

One Format at a Time

Only one data format should be active at a time for a given request or response. If a format is set to true inside the script, all other format variables must explicitly be set to false. Otherwise, multiple formats may remain active simultaneously and cause unexpected results on the backend or client side.

Recommended usage:

// We want to send the request to the backend in gzip format
request_encoding_gzip = true
request_encoding_deflate = false
request_encoding_br = false
request_encoding_zstd = false
request_encoding_compress = false
request_encoding_identity = false

Header Consistency

When an encoding variable is changed, the Content-Encoding value in the request or response headers must also be set to the same value. A mismatch between the format variable and the header value will cause the client or backend to fail when decompressing the body.

request_encoding_gzip = true
request_headers["Content-Encoding"] = "gzip"

When to Use Script, When to Use Routing Settings

  • Routing setting (override): Use when a fixed rule is to be applied for all requests (e.g., every request must go to the backend as gzip). This is the safer, less error-prone option.
  • Script: Use when the decision must be made dynamically at runtime (e.g., use a different format based on the client's IP address or a header value). Inside the script, all format variables and the corresponding headers must be managed together.

If both methods are used at the same time, the script has the final say.

Message Variables

Flow VariablesValue LocationData TypeAllowed OperationDescriptionExample Usage
message_correlationIdClient → ApinizerStringRead, WriteWhen the request from client reaches Apinizer, Apinizer gives the request a unique ID and this ID is also added to the response. This unique ID value can be accessed with this variable.String value= message_correlationId;

message_correlationId= "<new value>";
message_cacheHitRuntimebooleanRead, WriteIndicates whether the request was served from the cache. This value is written to the "Cache Hit" field of the traffic logs. It can be changed by assigning true or false in the script, so scenarios that implement their own caching logic in a script can report the request as served from cache. Writing is only effective on the HTTP pipeline.boolean value= message_cacheHit;

message_cacheHit= true;
environment_idClient → ApinizerStringReadEnvironment ID information where API traffic is received and responded.String value= environment_id;
environment_nameClient → ApinizerStringReadEnvironment name information where API traffic is received and responded.String value= environment_name;

Environment Variables

Flow VariablesValue LocationData TypeAllowed OperationDescriptionExample Usage
apiProxyGroup_idClient → ApinizerStringReadIf the request from client is handled by API Proxy Group, used to access API Proxy Group's ID information.String value= apiProxyGroup_id;
apiProxyGroup_nameClient → ApinizerStringReadIf the request from client is handled by API Proxy Group, used to access API Proxy Group's name information.String value= apiProxyGroup_name;
apiProxy_idClient → ApinizerStringReadIf the request from client is handled by API Proxy, used to access API Proxy's ID information.String value= apiProxy_id;
apiProxy_nameClient → ApinizerStringReadIf the request from client is handled by API Proxy, used to access API Proxy's name information.String value= apiProxy_name;
apiProxy_relativePathClient → ApinizerStringReadIf the request from client is handled by API Proxy, used to access the relative path the API Proxy is published under.String value= apiProxy_relativePath;
apiMethod_idClient → ApinizerStringReadIf the request from client is handled by API Proxy Method, used to access API Proxy Method's ID information.String value= apiMethod_id;
apiMethod_nameClient → ApinizerStringReadIf the request from client is handled by API Proxy Method, used to access API Proxy Method's name information.String value= apiMethod_name;
apiMethod_soapActionClient → ApinizerStringReadIf the request from client is handled by API Proxy Method, used to access the "Soap Action" value of the API Proxy Method. Valid for SOAP type API Proxies.String value= apiMethod_soapAction;
apiMethod_httpMethodClient → ApinizerStringReadIf the request from client is handled by an API Proxy Endpoint, used to access the "Http Method" value of that endpoint.String value= apiMethod_httpMethod;
apiMethod_endpointClient → ApinizerStringReadIf the request from client is handled by an API Proxy Endpoint, used to access the endpoint value.String value= apiMethod_endpoint;
apiMethod_backend_httpMethodClient → ApinizerStringReadIf the request from client is handled by an API Proxy Endpoint, used to access the "Http Method" value the endpoint will use on the Backend API.String value= apiMethod_backend_httpMethod;
apiMethod_backend_endpointClient → ApinizerStringReadIf the request from client is handled by an API Proxy Endpoint, used to access the "Endpoint" value the endpoint will use on the Backend API.String value= apiMethod_backend_endpoint;
dateTime_yearRuntimeIntegerReadUsed to access year information at runtime.Integer value= dateTime_year;
dateTime_monthRuntimeIntegerReadUsed to access month information at runtime.Integer value= dateTime_month;
dateTime_dayOfWeekRuntimeIntegerReadUsed to access the day-of-week information at runtime. Takes values between 1 (Monday) and 7 (Sunday).Integer value= dateTime_dayOfWeek;
dateTime_dayOfMonthRuntimeIntegerReadUsed to access the day-of-month information at runtime. Takes values between 1 and 31.Integer value= dateTime_dayOfMonth;
dateTime_hourRuntimeIntegerReadUsed to access hour information at runtime. Takes values between 0 and 23.Integer value= dateTime_hour;
dateTime_minuteRuntimeIntegerReadUsed to access the minute information of the UTC time at runtime. Takes values between 0 and 59.Integer value= dateTime_minute;
dateTime_secondRuntimeIntegerReadUsed to access the second information of the UTC time at runtime. Takes values between 0 and 59.Integer value= dateTime_second;
dateTime_epochMillisRuntimeLongReadUsed to access the epoch milliseconds of the UTC time at runtime, i.e. the milliseconds elapsed since 1970-01-01T00:00:00Z.Long value= dateTime_epochMillis;
dateTime_formattedTextRuntimeStringReadUsed to access the UTC date-time at runtime in "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" format.String value= dateTime_formattedText;
date_formattedTextRuntimeStringReadUsed to access the UTC date at runtime in "yyyy-MM-dd" format.String value= date_formattedText;
time_formattedTextRuntimeStringReadUsed to access the UTC time at runtime in "HH:mm:ss" format.String value= time_formattedText;
environment_certificateMapRuntimeMap<String, X509Certificate>ReadUsed to access "X509Certificate" values loaded in the environment at runtime. The entity name is used for access.import java.security.cert.X509Certificate;

X509Certificate obj= environment_certificateMap.get("obj-name");
environment_privateKeyMapRuntimeMap<String, java.security.PrivateKey>ReadUsed to access "Private Key" values loaded in the environment at runtime.import java.security.PrivateKey;

PrivateKey obj= environment_privateKeyMap.get("obj-name");
environment_publicKeyMapRuntimeMap<String, java.security.PublicKey>ReadUsed to access "Public Key" values loaded in the environment at runtime.import java.security.PublicKey;

PublicKey obj= environment_publicKeyMap.get("obj-name");
environment_secretKeyMapRuntimeMap<String, javax.crypto.spec.SecretKeySpec>ReadUsed to access "Secret Key" values loaded in the environment at runtime.import javax.crypto.spec.SecretKeySpec;

SecretKeySpec obj= environment_secretKeyMap.get("obj-name");
environment_keyStoreMapRuntimeMap<String, java.security.KeyStore>ReadUsed to access "Keystore" values loaded in the environment at runtime.import java.security.KeyStore

KeyStore obj= environment_keyStoreMap.get("obj-name");
environment_jwkMapRuntimeMap<String, com.apinizer.common.apigw.jwk.Jwk>ReadUsed to access "JWK" values loaded in the environment at runtime.import com.apinizer.common.apigw.jwk.Jwk

Jwk obj= environment_jwkMap.get("obj-name");
environmentVariableMapRuntimeMap<String, String> (read-only)ReadProvides access to environment variables defined in the active environment from the script body. Since ${variable} placeholders are not resolved inside the script body, this method is used instead. Values marked as Secret are returned in their resolved (plain) form. Keys are case-insensitive. Mutation is not supported, but iteration (keySet()/values()/entrySet()) is supported.String dbHost= environmentVariableMap.get("dbHost");

if (environmentVariableMap.containsKey("apiKey")) { ... }

Credential Variables

Flow VariablesValue LocationData TypeAllowed OperationDescriptionExample Usage
credential_usernameRuntimeStringReadUsed to access "username" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.String value= credential_username;
credential_emailRuntimeStringReadUsed to access "email" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.String value= credential_email;
credential_fullNameRuntimeStringReadUsed to access "full name" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.String value= credential_fullName;
credential_secretKeyRuntimejavax.crypto.SecretKeyReadUsed to access "Secret Key" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.javax.crypto.SecretKey value=credential_secretKey;
credential_certificateRuntimejava.security.cert.X509CertificateReadUsed to access "Certificate" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.java.security.cert.X509Certificate value=credential_certificate;
credential_publicKeyRuntimejava.security.PublicKeyReadUsed to access "Public Key" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.java.security.PublicKey value=credential_publicKey;
credential_privateKeyRuntimejava.security.PrivateKeyReadUsed to access "Private Key" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.java.security.PrivateKey value=credential_privateKey;
credential_keyStoreRuntimejava.security.KeyStoreReadUsed to access "Keystore" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.java.security.KeyStore value=credential_keyStore;
credential_trustStoreRuntimejava.security.KeyStoreReadUsed to access "Truststore" information of the credential set before the policy. If credential doesn't exist or is not set, its value is null.java.security.KeyStore value=credential_trustStore;
credential_jwkForValidationAndSignRuntimecom.apinizer.common.apigw.jwk.JwkReadUsed to access the "JWK used for signing and signature validation" of the credential set before the policy. If credential doesn't exist or is not set, its value is null.com.apinizer.common.apigw.jwk.Jwk value=credential_jwkForValidationAndSign;
credential_jwkForDecryptionAndEncryptionRuntimecom.apinizer.common.apigw.jwk.JwkReadUsed to access the "JWK used for encryption and decryption" of the credential set before the policy. If credential doesn't exist or is not set, its value is null.com.apinizer.common.apigw.jwk.Jwk value=credential_jwkForDecryptionAndEncryption;
credentialMapRuntimeMap (read-only)ReadProvides access to any credential in the active environment by username or client ID. While the credential_* variables above return only the authenticated credential of the request, this method allows reading fields of other credentials as well. The returned object exposes resolved password, username, email, full name, custom key/value metadata, organization metadata, project/application metadata, role names, environment-scoped password, expiration, grant type, and key material (Secret Key, Certificate, Public Key, Private Key, Keystore, Truststore, JWK). Key enumeration is not supported and values cannot be written.def cred= credentialMap.get("acme-app");

String pwd= cred?.getResolvedPassword();

java.security.PublicKey pk= cred?.getPublicKey();

Custom Variables

There may be a need to temporarily define variables with policies on the Request or Response pipeline and use them in the next policy. In this case, the customVariableMap variable is used.

Variable NameTypeAccessDescriptionExample Usage
customVariableMapMap<String, String>Read, WriteMay need to temporarily define variables with policies in Request or Response pipeline and use them in the next policy. In this case, "customVariableMap" variable is used.

For example; You may need to access and change the value of the "testVariable" variable created with business rule policy in the policy before the script policy of an API Proxy in the script policy. In this case, the value assigned to this variable is read by saying customVariableMap.get("testVariable"). Similarly, to create a custom variable in the script policy, it should be used as customVariableMap.put("testVariable","test value"). Thus, in the next policy, the value added in the script policy can be accessed by creating a variable of custom variable type and named "testVariable".
String value = customVariableMap.get("testVariable");

customVariableMap.put("testVariable", "test value");

Important Restrictions

uyarı

Pipeline Restrictions:

  • Script Policy added to Request pipeline cannot access variables in Response pipeline.
  • Script Policy added to Response pipeline can only read variables in Request pipeline.

Cache Access

The cache variable is used to write to, read from and delete entries in the distributed cache from a script policy. It shares the same cache area as the Cache Policy; the storage is distributed, so all gateway (worker) servers see the same data.

MethodSignatureReturnsBehavior
getcache.get(String key)String | nullReturns the cached value. Returns null if there is no entry, the key is blank, or an error occurs.
putcache.put(String key, Object value, long ttlSeconds)booleanStores the value for ttlSeconds seconds. Does nothing and returns false if the key is blank or ttlSeconds is zero or negative.
deletecache.delete(String key)booleanDeletes the entry. Returns true if the deletion succeeds.
import groovy.json.JsonOutput
import groovy.json.JsonSlurper

def key = "profile|" + request_usernameOrKey
def cached = cache.get(key)
if (cached == null) {
def fresh = JsonOutput.toJson([name: "Acme", tier: "gold"])
cache.put(key, fresh, 600) // store for 600 seconds
cached = fresh
}
def profile = new JsonSlurper().parseText(cached)
uyarı
  • The returned value is always text. Even if you pass an object or a Map to put, get returns its text representation. For JSON/XML data you must serialize before put and parse after get.
  • TTL is mandatory and expressed in seconds. Storing without expiry is not supported.
  • There is no separate namespace. Since the same area as the Cache Policy is used, use a distinctive prefix (such as profile|...) to avoid key collisions.
  • Cache errors are not surfaced to the script. All errors are swallowed and logged; cache calls never throw, they return null or false.

Deleting the Policy

For steps to delete this policy and operations to be performed when it is in use, see the Removing Policy from Flow section on the Policy Management page.

Exporting/Importing the Policy

For export and import steps of this policy, see the Export/Import page.

Connecting Policy to API

For the process of how to connect this policy to APIs, see the Connecting Policy to API section on the Policy Management page.

Advanced Features

FeatureDescription and Steps
Script Test Dialog- Opens with Try It button.
- Sample data is entered by selecting Request/Response region.
- Execution result is examined as JSON and script is improved.
Context Value Library- Category is selected from Context Values select component.
- When selection is made, value is copied to clipboard.
- Environment information is obtained by using directly in script.
WebSocket/gRPC Adaptation- If proxy type is WebSocket/gRPC, variable lists are automatically narrowed.
- Appropriate message flow variables are provided.
- Script can manage errors in these protocols.

Best Practices

Things to Do and Best Practices

CategoryDescription / Recommendations
Script ConfigurationBad: Writing all logic in a single function.
Good: Breaking logic into functions.
Best: Keeping common functions in shared modules and keeping script simple.
Error ManagementBad: Swallowing errors and waiting for default 500.
Good: Setting responseErrorMessageToClient in error cases.
Best: Setting both message and statusCodeToClient value according to business scenario.
VersioningBad: Changing script directly in prod environment.
Good: Taking export before changes.
Best: Importing new version in test environment and deploying, then moving to live.
Condition UsageBad: Allowing policy to run on every request.
Good: Adding basic path condition.
Best: Specifying conditions with header, method, and environment combinations.
Performance MonitoringBad: Not tracking completion time of async scripts.
Good: Monitoring script durations in logs.
Best: Profiling and optimizing script if latency increases, using cache if needed.

Security Best Practices

Security AreaDescription / Warnings
Data MaskingMask personal data in response, perform regex validation in script.
Input ValidationCheck expected format in parameters taken into script, return error code if incorrect.
Exception ManagementCatch unexpected errors with try/catch blocks, log them, provide limited information to user.
External CallsIf you will make external system calls within script, set timeout and retry limits; prefer async mode.
Authorization LogicPrevent unauthorized access by centralizing header or JWT claim checks in script.

Things to Avoid

CategoryDescription / Warnings
Long-Running OperationsWhy avoid: Blocks gateway threads in Sync mode.
Alternative: Switch to Async mode or delegate to background service.
Hard-coded URLWhy avoid: Script breaks when environment changes.
Alternative: Use context value or environment variables.
Untested Code in Global ScriptWhy avoid: Affects all API Proxy traffic.
Alternative: Test as local script first, then globalize.
Leaving Error Message EmptyWhy avoid: Client receives ambiguous error.
Alternative: Set descriptive message in Error Message Customization section.

Performance Tips

CriterionRecommendation / Impact
Script ComplexityRecommendation: Keep loops and parsing operations minimal.
Impact: Gateway latency decreases.
Data StructuresRecommendation: Use lightweight map instead of ready libraries for large JSON transformations.
Impact: Reduces memory usage.
Condition EngineRecommendation: Do not define conditions when not needed; if defined, keep specific.
Impact: Policy evaluation time is optimized.
Async UsageRecommendation: Select Async in scripts containing network calls or long IO.
Impact: Reduces client wait time, increases throughput.
Test and MonitoringRecommendation: Track duration metric in Script Test module, log situations above limit.
Impact: Performance degradations are detected early.

Frequently Asked Questions (FAQ)

CategoryQuestionAnswer
GeneralWhen should Script Policy be used?Should be used when you want to solve data transformation and business logic needs at gateway level that are not covered by rule engine or ready policies.
GeneralHow should I decide between Groovy and Javascript?Make selection according to team expertise, existing libraries, and operations to be performed in script; if you are close to Java ecosystem choose Groovy, if you will work with frontend team you can choose Javascript.
TechnicalWhat happens if script does not complete in Async mode?Default response is returned until async process completes; results are monitored in logs, retry mechanism can be added if needed.
TechnicalHow does Context Value work?When EnumScriptContextValue values are selected, relevant environment/metadata information is copied to clipboard; you can access runtime data by using as string within script.
UsageDoes script test screen affect real traffic?No, test screen works in isolation; simulates script on entered sample data.
UsageCan script policy be shared across multiple API Proxies?When created globally, it can be used in all API Proxies; local copies provide proxy-based customization.