Skip to content

Latest commit

 

History

History
221 lines (163 loc) · 10.9 KB

File metadata and controls

221 lines (163 loc) · 10.9 KB
description
This page provides the technical details of the Javascript policy

Javascript

Overview

You can use this policy to run Javascript scripts at every stage of Gateway processing.

Functional and implementation information for the javascript policy is organized into the following sections:

Examples

{% hint style="warning" %} This policy can be applied to v2 APIs and v4 proxy APIs. It cannot be applied to v4 message APIs. {% endhint %}

{% tabs %} {% tab title="Proxy API example" %} Example 1

This script stops the processing if the request contains a certain header:

if (request.headers.containsKey('X-Gravitee-Break')) {
    result.key = 'RESPONSE_TEMPLATE_KEY';
    result.state = State.FAILURE;
    result.code = 500
    result.error = 'Stop request processing due to X-Gravitee-Break header'
} else {
    request.headers.set('X-JavaScript-Policy', 'ok');
}

To customize the error sent by the policy:

result.key = 'RESPONSE_TEMPLATE_KEY';
result.state = State.FAILURE;
result.code = 400
result.error = '{"error":"My specific error message","code":"MY_ERROR_CODE"}'
result.contentType = 'application/json'

Example 2

The following shows how to use the javascript policy to transform JSON content.

Assuming the request body below (input body content):

[
    {
        "age": 32,
        "firstname": "John",
        "lastname": "Doe"
    }
]

You can run the following JavaScript script:

var content = JSON.parse(response.content);
content[0].firstname = 'Hacked ' + content[0].firstname;
content[0].country = 'US';

JSON.stringify(content);

And the request body being passed to the API will be (output body content):

[
    {
        "age": 32,
        "firstname": "Hacked John",
        "lastname": "Doe",
        "country": "US"
    }
]

Example 3

Assume that you sent the request body modified above to an echo API. You can run the following:

var content = JSON.parse(response.content);
content[0].firstname = content[0].firstname.substring(7);
delete content[0].country;
JSON.stringify(content);

And the response message will be:

[
    {
        "age": 32,
        "firstname": "John",
        "lastname": "Doe"
    }
]

{% endtab %} {% endtabs %}

Configuration

"javascript": {
    "onRequestScript": "response.headers.remove('X-Powered-By');",
    "onResponseScript": "response.headers.set('X-Gravitee-Gateway-Version', '0.14.0');",
    "onRequestContentScript": "" // Not executed if empty
    "onResponseContentScript": "" // Not executed if empty
}

Phases

The phases checked below are supported by the javascript policy:

v2 PhasesCompatible?v4 PhasesCompatible?
onRequesttrueonRequesttrue
onResponsetrueonResponsetrue
onRequestContenttrueonMessageRequestfalse
onResponseContenttrueonMessageResponsefalse

onRequest / onResponse

Some variables are automatically bound to the JavaScript script to allow users to use them and define the policy behavior:

NameDescription
requestInbound HTTP request
responseOutbound HTTP response
contextPolicyContext used to access external components such as services and resources
resultJavaScript script result

Request or response processing can be interrupted by setting the result state to FAILURE. By default, it will throw a 500 - internal server error, but you can override this behavior with the following properties:

  • code: An HTTP status code
  • error: The error message
  • key: The key of a response template

onRequestContent / onResponseContent

In the onRequestContent phase you have access to the content object, also known as the request body. You can modify this object.

In the onResponseContent phase you have access to the content object, also known as the response message. You can modify this object.

For example, you can transform request or response body content by applying a JavaScript script on the OnRequestContent phase or the OnResponseContent phase.

{% hint style="warning" %} When working with scripts on OnRequestContent or OnResponseContent phase, the last instruction of the script must be the new body content that would be returned by the policy. {% endhint %}

Dictionaries and Properties

Both dictionaries (defined at the environment level) and properties (defined at the API level) can be accessed from the JavaScript script using:

  • context.dictionaries() for dictionaries
  • context.properties() for properties

Here is an example of how to set a request header based on a property:

request.headers.set('X-JavaScript-Policy', context.properties()['KEY_OF_MY_PROPERTY']);

Options

The javascript policy can be used to configure the request, response, and metrics objects:

{% tabs %} {% tab title="onRequest" %}

Object Property Type Description
request id string -
request transactionId string -
request uri string -
request path string -
request pathInfo string -
request contextPath string -
request parameters multivalue map -
request pathParameters multivalue map -
request headers iterable map <string, string> -
request method enum -
request version enum -
request timestamp long -
request remoteAddress string -
request localAddress string -
request scheme string -
request sslSession javax.net.ssl.SSLSession -
request metrics object
{% endtab %}

{% tab title="onResponse" %} In the onResponse phase, you have access to the request, the response and the context object.

Object Property Type Description
response status int -
response reason String -
response headers iterable map <string, string> -
{% endtab %}

{% tab title="Metrics" %} It is highly advisable to use the Metrics Reporter in order to manage the metrics. However, the request object does contain a metrics object.

Note that the metrics object changes in the different processing phases. Some properties may not make sense in certain phases.

ObjectPropertyTypeDescription
metricsapiStringID of the API
metricsapiResponseTimeMslongResponse time spend to call the backend upstream
metricsapplicationStringID of the consuming application
metricsendpointString-
metricserrorKeyStringKey of the error if the policy chain is failing
metricshostStringHost header value
metricshttpMethodenum-
metricslocalAddressString-
metricslogobject-
metricsmappedPathString-
metricsmessageString-
metricspathString-
metricsplanStringID of the plan
metricsproxyLatencyMslongLatency of the gateway to apply policies
metricsproxyResponseTimeMslongGlobal response time to process and respond to the consumer
metricsremoteAddressString-
metricsrequestContentLengthlong-
metricsrequestIdString-
metricsresponseContentLengthlong-
metricssecurityTokenString-
metricssecurityTypeenum-
metricsstatusint-
metricssubscriptionStringID of the subscription
metricstenantStringgateway tenant value
metricstransactionIdString-
metricsuriString-
metricsuserStringEnd-user doing the call (in case of OAuth2 / JWT / Basic Auth)
metricsuserAgentStringValue of the user-agent header
metricszoneStringGateway zone
{% endtab %} {% endtabs %}

Errors

HTTP status codeMessage
500The JavaScript script cannot be parsed/compiled or executed (mainly due to a syntax error)

Changelogs

{% @github-files/github-code-block url="https://github.com/gravitee-io/gravitee-policy-javascript/blob/master/CHANGELOG.md" %}