Send Docs Feedback

Note: Most user interface tasks can be performed in Edge Classic or the New Edge experience. For an overview, getting started topics, and release notes specific to the New Edge experience, see the docs.

JavaScript policy

What

This policy lets you add custom JavaScript code that executes within the context of an API proxy flow. In your custom JavaScript code, you can use the objects, methods, and properties of the Apigee Edge JavaScript object model. The object model lets you get, set, and remove variables in the proxy flow conext. You can also use basic cryptographic functions that are provided with the object model. 

Where

You can attach this policy to execute custom JavaScript code at any location in the API proxy flow.

ProxyEndpoint TargetEndpoint
    PreFlow Flow PostFlow PreFlow Flow PostFlow    
Request    
    レスポンス
    PostFlow Flow PreFlow PostFlow Flow PreFlow    

About

There are many use cases for the JavaScript policy. For example, you can get and set flow variables, execute custom logic and perform fault handling, extract data from requests or responses, dynamically edit the backend target URL, and much more. This policy allows you to implement custom behavior that is not covered by any other standard Edge policies. In fact, you can use a JavaScript policy to achieve many of the same behaviors implemented by other policies, like AssignMessage and ExtractVariable.

One use case we don't recommend for the JavaScript policy is logging. The Message Logging policy is much better suited for logging to third-party logging platforms such as Splunk, Sumo, and Loggly, and you improve API proxy performance by executing the Message Logging policy in the PostClientFlow, which executes after the response has been sent back to the client.

Basically, the JavaScript policy specifies the name of the JavaScript source file to execute when the step to which the policy is attached executes. The source file is always stored in a standard location within the proxy bundle: apiproxy/resources/jsc. Or, you can also store the source code in a resource file at the environment or organization level. For instructions, see Resource files. You can also upload your JavaScript through the management UI proxy editor.

JavaScript source files must always have a .js extension.

See Supported software and supported versions for the currently supported version of JavaScript.

Samples

Here's a common use case: extracting data from a request body, storing it in a flow variable, and using that flow variable elsewhere in the proxy flow. Let's say you have an app where the user enters their name in an HTML form and submits it. You want the API proxy to extract the form data and dynamically add it to the URL used to call the backend service. How would you do this in a JavsScript policy?

Note: If you want to try out this example, we assume you've created a new proxy in the proxy editor. When you create it, just give it a backend service URL of: http://www.example.com. For this example, we're going to rewrite the backend URL dynamically. If you don't know how to create a new proxy, refer to the getting started tutorial. .

  1. In Edge UI, open the proxy that you created in the proxy editor.
  2. Select the Develop tab.
  3. From the New menu, select New Script.
  4. In the dialog, select JavaScript and give the script a name, like js-example.
  5. Paste the following code in the code editor and save the proxy. The important thing to notice is the context object. This object is available to the JavaScript code anywhere in the proxy flow. It's used to obtain flow-specific constants, to call useful get/set methods, and for more operations. This object part is of Edge's JavaScript Object Model. Note, too, that the target.url flow variable is a built-in, read/write variable that is accessible in the Target Request flow. When we set that variable with the API URL, Edge makes its backend call to that URL. We've essentially rewritten the original target URL, which was whatever you specified when you created the proxy (e.g., 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);
    }
    
     
    1. From the New Policy menu, select JavaScript.
    2. Give the policy a name, like target-rewrite. Accept the defaults, and save the policy.
    3. If you select the Proxy Endpoint Preflow in the Navigator, you'll see that the policy was added to that flow.
    4. In the Navigator, select the Target Endpoint PreFlow icon.
    5. From the Navigator, drag the JavaScript policy onto the Request side of the Target Endpoint in the flow editor.
    6. Save.
    7. Call the API like this, substituting your correct org name and proxy name as appropriate:
    curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST -d 'user=Will' http://myorg-test.apigee.net/js-example

    One final thing, let's take a look at the XML definition for the JavaScript policy used in this example. The important thing to note is that the <ResourceURL> element is used to speicfy the JavaScript source file to execute. This same pattern is used for any JavaScript source file: jsc://filename.js. If you're JavaScript code requires includes, you can use one or more <IncludeURL> elements to do that, as described later in this reference.

    <?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>

    You can add a <Property> element in configuration, then retrieve the element's value with JavaScript at runtime.

    Use the element's name attribute to specify the name with which to access the property from JavaScript code. The <Property> element's value (the value between the opening and closing tags) is the literal value that will be received by the JavaScript.

    In JavaScript, you retrieve the policy property value by accessing it as a property of the Properties object, as in the following:

    • Configure the property. Here, 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 with JavaScript. Here, the retrieved value -- a variable name -- is then used by the getVariable function 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);

    For examples and a discussion of error handling techniques that you can use in a JavaScript callout, see this post in the Apigee Community. Suggestions offered in the Apigee Community are for information only and do not necessarily represent best practices recommended by Apigee.


    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>
        <ResourceURL>jsc://my-javascript-source-file</ResourceURL>
        <IncludeURL>jsc://a-javascript-library-file</IncludeURL>
    </Javascript>
    

    <Javascript> Attributes

    <Javascript name="Javascript-1" enabled="true" continueOnError="false" async="false" timeLimit="200">

    The following attributes are specific to this policy.

    Attribute 説明 デフォルト Presence
    timeLimit

    Specifies the maximum time (in milliseconds) that the script is permitted to execute.

    Note: For free trial accounts, execution time is limited to 200 ms.

    該当なし Required

    The following attributes are common to all policy parent elements.

    Attribute 説明 デフォルト Presence
    name

    The internal name of the policy. Characters you can use in the name are restricted to: A-Z0-9._\-$ %. However, the Edge management UI enforces additional restrictions, such as automatically removing characters that are not alphanumeric.

    Optionally, use the <DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

    該当なし Required
    continueOnError

    Set to false to return an error when a policy fails. This is expected behavior for most policies.

    Set to true to have flow execution continue even after a policy fails.

    false Optional
    enabled

    Set to true to enforce the policy.

    Set to false to "turn off" the policy. The policy will not be enforced even if it remains attached to a flow.

    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:

    該当なし

    If you omit this element, the value of the policy's name attribute is used.

    Presence: Optional
    Type: 文字列

     

    <IncludeURL> element

    Specifies a JavaScript library file to be loaded as dependency to the main JavaScript file specified with the <ResourceURL> element. The scripts will be evaluated 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 with additional <IncludeURL> elements.

    If your JavaScript files are stored at the organization or environment level, be sure they were uploaded correctly with cURL using the -F option or as a file attachment through a REST client. Content-Type is multipart/form-data. For more information, see Resource files.

    <IncludeURL>jsc://my-javascript-dependency.js</IncludeURL>
    Default: なし
    Presence: Optional
    Type: 文字列

    See the Basic Example in the Samples section.

    <Property> element

    Specifies a property you can access from JavaScript code at runtime.

    <Properties>
        <Property name="propName">propertyValue</Property>
    </Properties>
    Default: なし
    Presence: Optional
    Type: 文字列

    属性

    Attribute 説明 デフォルト Presence
    name

    Specifies the name of the property.

    該当なし Required.

    See the example in the Samples section.

    <ResourceURL> element

    Specifies the main JavaScript file that will execute 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), or at the organization or environment scopes for reuse across multiple API proxies, as described in Resource files. Your code can use the objects, methods, and properties of the JavaScript object model.

    <ResourceURL>jsc://my-javascript.js</ResourceURL>
    Default: なし
    Presence: Required
    Type: 文字列

    See the Basic Example in the Samples section.

    Usage notes

    A JavaScript policy contains no actual code. Instead, a JavaScript policy references a JavaScript 'resource' and defines the Step in the API flow where the JavaScript executes. You can upload your script through the Management UI proxy editor, or you can include it in the /resources/jsc directory in API proxies that you develop locally.

    System calls are not permitted by the security model. For example: internal file system reads or writes, or getting current user info, the process list, or CPU/memory utilization. Although some such calls may be functional, they are unsupported and liable to be actively disabled at any time. For forward compatibility, you should avoid making such calls in your code.

    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. A typical pattern looks like this:

    context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"))
    

    The context object is part of the Apigee Edge JavaScript Object Model. For more information, see JavaScript object model

    Error reference

    This section describes the error messages and flow variables that are set when this policy triggers an error. This information is important to know if you are developing fault rules for a proxy. To learn more, see What you need to know about policy errors and Handling faults.

    Error code prefix

    steps.javascript (What's this?)

    Runtime errors

    These errors can occur when the policy executes.

    Error name HTTP
    Status
    Occurs when
    ScriptExecutionFailed 500 A runtime error occurred in the JavaScript code. See the fault string for details.
    ScriptExecutionFailedLineNumber 500 An error occurred in the JavaScript code. See the fault string for details.
    ScriptSecurityError 500 A security error occurred when the JavaScript executed. See the fault string for details.

    Deployment errors

    These errors can occur when you deploy a proxy containing this policy.

    Error name Occurs when
    WrongResourceType In the <ResourceURL> and <IncludeURL> elements, you must refer to a JavaScript file correctly using the jsc resource type. For example, here is the correct way to refer to the JavaScript file in the policy:
    <ResourceURL>jsc://JavaScript-1.js</ResourceURL>
    NoResourceForURL The <ResourceURL> and <IncludeURL> elements refer to a JavaScript file that does not exist.
    ScriptCompilationFailed An error occured when Edge tried to compile the JavaScript code. Refer to the error message for details.

    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 set (Learn more) Where
    [prefix].[policy_name].failed The [prefix] is javascript.
    The [policy_name] is the name of the policy that threw the error.
    javascript.JavaScript-1.failed = true
    fault.[error_name] [error_name] is the specific error name to check for as listed in the table above. fault.name Matches "ScriptExecutionFailed"

    Example error response

    For error handling, the best practice is to trap the errorcode part of the error response. Do not rely on the text in the faultstring, because it could change.

    {
      "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>

    スキーマ

    Each policy type is defined by an XML schema (.xsd). For reference, policy schemas are available on GitHub.

    関連トピック

    Apigee Community articles

    You can find these related articles on the Apigee Community:

    Help or comments?