This page applies to Apigee and Apigee hybrid.
View
Apigee Edge documentation.
The JavaScript policy lets you add custom JavaScript code that executes in the context of the API proxy flow. This policy lets you implement custom behavior not otherwise covered by Apigee policies.
In your custom JavaScript code, you can use the objects, methods, and properties of the Apigee JavaScript object model. You can get, set, and remove variables in the proxy flow context, execute custom logic, perform fault handling, extract data from requests or responses, and dynamically edit the backend target URL. You can also use basic cryptographic functions that are available in the object model.
The JavaScript policy lets you specify a JavaScript source file to execute, or you can include
JavaScript code directly in the policy's configuration using the <Source>
element. Either way, the JavaScript code executes when the step where the policy is attached
executes.
For the source file option, the source code is always stored in a
standard location in the proxy bundle: apiproxy/resources/jsc. Or, you can
store the source code in a resource file at the environment or organization level. For
instructions, see Resource files.
You can also upload JavaScript using the Apigee UI proxy editor.
Apigee does not recommend using the JavaScript policy for the following:
- Logging. The MessageLogging policy is better suited for logging with third-party logging platforms such as Splunk, Sumo, and Loggly. This policy also improves API proxy performance by executing in the PostClientFlow after the response returns to the client.
- Replacing Apigee policies. The JavaScript policy does not replace the capabilities of Apigee policies. If the capabilities you need are available in an Apigee policy, use that policy instead of implementing a custom JavaScript solution. Custom JavaScript code might not match the performance and optimization of Apigee policies.
JavaScript source files must have a .js extension.
Apigee supports JavaScript running on the Rhino JavaScript engine 1.7.13.
This policy is an Extensible policy and use of this policy might have cost or utilization implications, depending on your Apigee license. For information on policy types and usage implications, see Policy types.
Samples
Rewrite the target URL
A common use case involves extracting data from a request body, storing it in a flow variable, and then using that flow variable elsewhere in the proxy flow. For example, suppose a user enters their name in an HTML form and submits it. To extract the form data and dynamically add it to the backend service URL, use a JavaScript policy.
- In the Apigee UI, open the proxy you created in the proxy editor.
- Select the Develop tab.
- From the New menu, select New Script.
- In the dialog, select JavaScript and name the script
js-example. - Paste the following code in the code editor and save the proxy. The
contextobject is available to JavaScript code anywhere in the proxy flow. It obtains flow-specific constants, calls usefulget/setmethods, and performs other operations. This object is part of the Apigee JavaScript object model. Thetarget.urlflow variable is a built-in, read/write variable accessible in the Target Request flow. When you set that variable with the API URL, Apigee calls that backend URL. This rewrites the original target URL, which was the URL you specified when you created the proxy (for example,http://www.example.com).if (context.flow=="PROXY_REQ_FLOW") { var username = context.getVariable("request.formparam.user"); context.setVariable("info.username", username); } if (context.flow=="TARGET_REQ_FLOW") { context.setVariable("request.verb", "GET"); var name = context.getVariable("info.username"); var url = "http://mocktarget.apigee.net/" context.setVariable("target.url", url + "?user=" + name); }
- From the New Policy menu, select JavaScript.
- Name the policy
target-rewrite. Accept the defaults, and save the policy. - After you select the Proxy Endpoint Preflow in the Navigator, the policy is added to that flow.
- In the Navigator, select Target Endpoint PreFlow.
- In the Navigator, drag the JavaScript policy onto the Request side of the Target Endpoint in the flow editor.
- Save.
- Substitute your organization name and proxy name when you call the API:
curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST -d 'user=Will' http://myorg-test.apigee.net/js-example
Examine the XML definition for the JavaScript policy used in
this example. The <ResourceURL>
element specifies the JavaScript source file to execute. This pattern applies to any JavaScript source file: jsc://filename.js. If your JavaScript code
requires includes, use one or more <IncludeURL> elements, as described later in this document.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="target-rewrite"> <DisplayName>target-rewrite</DisplayName> <Properties/> <ResourceURL>jsc://js-example.js</ResourceURL> </Javascript>
Retrieve property value from JavaScript
You can add a <Property> element in the configuration and then retrieve its
value with JavaScript at runtime.
Use the element's name attribute to specify the name for accessing the
property from JavaScript code. The <Property> element's value (the value
between the opening and closing tags) is the literal value JavaScript receives.
In JavaScript, you retrieve the policy property value by accessing it as a property of the
Properties object, as follows:
- Configure the property. The property value is the variable name
response.status.code.<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JavascriptURLRewrite"> <DisplayName>JavascriptURLRewrite</DisplayName> <Properties> <Property name="source">response.status.code</Property> </Properties> <ResourceURL>jsc://JavascriptURLRewrite.js</ResourceURL> </Javascript>
- Retrieve the property using JavaScript. The
getVariablefunction then uses the retrieved variable name to retrieve the variable's value.var responseCode = properties.source; // Returns "response.status.code" var value = context.getVariable(responseCode); // Get the value of response.status.code context.setVariable("response.header.x-target-response-code", value);
Handling errors
For examples and a discussion of error handling techniques you can use in a JavaScript callout, see Correct way to return an error from a JavaScript policy. Suggestions in the Apigee Community are for informational purposes only and do not necessarily represent best practices recommended by Google.
Element reference
The element reference describes the elements and attributes of the JavaScript policy.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JavaScript-1"> <DisplayName>JavaScript 1</DisplayName> <Properties> <Property name="propName">propertyValue</Property> </Properties> <SSLInfo> <Enabled>trueFalse</Enabled> <ClientAuthEnabled>trueFalse</ClientAuthEnabled> <KeyStore>ref://keystoreRef</KeyStore> <KeyAlias>keyAlias</KeyAlias> <TrustStore>ref://truststoreRef</TrustStore> </SSLInfo> <IncludeURL>jsc://a-javascript-library-file</IncludeURL> <ResourceURL>jsc://my-javascript-source-file</ResourceURL> <Source>insert_js_code_here</Source> </Javascript>
<Javascript> Attributes
< languageVersion="VERSION_1_3" Javascript name="Javascript-1" enabled="true" continueOnError="false" async="false" timeLimit="200">
| Attribute | Description | Default | Presence |
|---|---|---|---|
| languageVersion |
Specifies the version of the JavaScript language the code is written in. Values include |
VERSION_DEFAULT | Optional |
| timeLimit |
Specifies the maximum time (in milliseconds) a script can
execute. For example, if a 200 ms limit is exceeded, the policy throws this error:
|
N/A | Required |
The following table describes attributes that are common to all policy parent elements:
| Attribute | Description | Default | Presence |
|---|---|---|---|
name |
The internal name of the policy. The value of the Optionally, use the |
N/A | Required |
continueOnError |
Set to Set to |
false | Optional |
enabled |
Set to Set to |
true | Optional |
async |
This attribute is deprecated. |
false | Deprecated |
<DisplayName> element
Use in addition to the name attribute to label the policy in the
management UI proxy editor with a different, natural-language name.
<DisplayName>Policy Display Name</DisplayName>
| Default |
N/A If you omit this element, the value of the policy's |
|---|---|
| Presence | Optional |
| Type | String |
<IncludeURL> element
Specifies a JavaScript library file to load as a dependency for the main JavaScript file
specified with the <ResourceURL> or <Source> element. The policy evaluates the scripts in the
order in which they are listed in the policy. Your code can use the objects, methods, and
properties of the JavaScript object model.
Include more than one JavaScript dependency resource using additional
<IncludeURL> elements.
<IncludeURL>jsc://my-javascript-dependency.js</IncludeURL>
| Default: | None |
| Presence: | Optional |
| Type: | String |
<Property> element
Specifies a property you can access from JavaScript code at runtime.
<Properties> <Property name="propName">propertyValue</Property> </Properties>
| Default: | None |
| Presence: | Optional |
| Type: | String |
Attributes
| Attribute | Description | Default | Presence |
|---|---|---|---|
| name |
Specifies the name of the property. |
N/A | Required |
Example
See the example in the Samples section.
<ResourceURL> element
Specifies the main JavaScript file that executes in the API flow. You can store this file
at the API proxy scope (under /apiproxy/resources/jsc in the API proxy bundle or in
the Scripts section of the API proxy editor's Navigator pane). Alternatively, store it at the organization or
environment scopes for reuse across multiple API proxies, as described in Managing resources. Your code can use the objects,
methods, and properties of the JavaScript object model.
<ResourceURL>jsc://my-javascript.js</ResourceURL>
| Default: | None |
| Presence: | Either <ResourceURL> or <Source> is required. If
both <ResourceURL> and <Source> are present, the policy ignores <ResourceURL>. |
| Type: | String |
Example
See the example in the Samples section.
<Source> element
You can insert JavaScript directly into the policy's XML configuration. The inserted JavaScript code executes when the policy executes in the API flow.
| Default: | None |
| Presence: | Either <ResourceURL> or <Source> is required. If
both <ResourceURL> and <Source> are present, the policy ignores <ResourceURL>. |
| Type: | String |
Example
<Javascript name='JS-ParseJsonHeaderFullString' timeLimit='200' > <Properties> <Property name='inboundHeaderName'>specialheader</Property> <Property name='outboundVariableName'>json_stringified</Property> </Properties> <Source> var varname = 'request.header.' + properties.inboundHeaderName + '.values.string'; var h = context.getVariable(varname); if (h) { h = JSON.parse(h); h.augmented = (new Date()).valueOf(); var v = JSON.stringify(h, null, 2) + '\n'; // further indent var r = new RegExp('^(\S*)','mg'); v= v.replace(r,' $1'); context.setVariable(properties.outboundVariableName, v); } </Source> </Javascript>
<SSLInfo> element
Specifies the properties used to configure TLS for all HTTP client instances created by the JavaScript policy.
<SSLInfo> <Enabled>trueFalse</Enabled> <ClientAuthEnabled>trueFalse</ClientAuthEnabled> <KeyStore>ref://keystoreRef</KeyStore> <KeyAlias>keyAlias</KeyAlias> <TrustStore>ref://truststoreRef</TrustStore> </SSLInfo>
| Default: | None |
| Presence: | Optional |
| Type: | String |
The process of configuring TLS for an HTTP client is the same process used to configure TLS for a TargetEndpoint/TargetServer. See Options for configuring TLS for more information.
Usage notes
Debugging JavaScript policy code
Use the print() function to output debug information to the transaction
output panel in the Debug tool. For details and examples, see Debug JavaScript with print() statements.
To view print statements in the Debug tool:
- Open the Debug tool and start a trace session for a proxy that contains your JavaScript policy.
- Call the proxy.
- In the Debug Tool, click Output from all Transactions to open the output
panel.

- Your print statements appear in this panel.
Flow Variables
This policy does not populate any variables by default. However, you can set and get flow
variables in your JavaScript code by calling methods on the context object. For example:
context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"))
The context object is part of the Apigee JavaScript object model.
Error reference
This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.
Runtime errors
These errors can occur when the policy executes.
| Fault code | HTTP status | Cause | Fix |
|---|---|---|---|
steps.javascript.ScriptExecutionFailed |
500 |
The JavaScript policy can throw many different types of ScriptExecutionFailed errors. Commonly
seen types of errors include
RangeError,
ReferenceError,
SyntaxError,
TypeError, and
URIError. |
build |
steps.javascript.ScriptExecutionFailedLineNumber |
500 |
An error occurred in the JavaScript code. See the fault string for details. |
N/A |
steps.javascript.ScriptSecurityError |
500 |
A security error occurred when the JavaScript executed. See the fault string for
details. |
N/A |
Deployment errors
These errors can occur when you deploy a proxy containing this policy.
| Error name | Cause | Fix |
|---|---|---|
InvalidResourceUrlFormat |
If the format of the resource URL specified within the <ResourceURL> or the <IncludeURL> element of the JavaScript policy is invalid, then the deployment of the API proxy fails. |
build |
InvalidResourceUrlReference |
If the <ResourceURL> or the <IncludeURL> elements
refer to a JavaScript file that does not exist, then the deployment of the API proxy fails.
The referenced source file must exist either the API proxy, environment, or organization level. |
build |
WrongResourceType |
This error occurs during deployment if the <ResourceURL> or the <IncludeURL>
elements of the JavaScript policy refer to any resource type other than jsc (JavaScript file). |
build |
NoResourceURLOrSource |
The deployment of the JavaScript policy can fail with this error if the <ResourceURL>
element is not declared or if the resource URL is not defined within this element.
<ResourceURL> element is a mandatory element. Or, The <IncludeURL> element is declared
but the resource URL is not defined within this element. The <IncludeURL> element is optional
but if declared, the resource URL must be specified within the <IncludeURL> element. |
build |
Fault variables
These variables are set when this policy triggers an error at runtime. For more information, see What you need to know about policy errors.
| Variables | Where | Example |
|---|---|---|
fault.name="fault_name" |
fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. | fault.name Matches "ScriptExecutionFailed" |
javascript.policy_name.failed |
policy_name is the user-specified name of the policy that threw the fault. | javascript.JavaScript-1.failed = true |
Example error response
{ "fault": { "faultstring": "Execution of SetResponse failed with error: Javascript runtime error: "ReferenceError: "status" is not defined. (setresponse.js:6)\"", "detail": { "errorcode": "steps.javascript.ScriptExecutionFailed" } } }
Example fault rule
<FaultRule name="JavaScript Policy Faults"> <Step> <Name>AM-CustomErrorResponse</Name> <Condition>(fault.name Matches "ScriptExecutionFailed") </Condition> </Step> <Condition>(javascript.JavaScript-1.failed = true) </Condition> </FaultRule>
Schema
Each policy type is defined by an XML schema (.xsd). For reference,
policy schemas
are available on GitHub.
Related topics
Apigee Community articles
You can find these related articles in the Apigee Community: