Implementation code examples

Example XSLT and GatewayScript code snippets.

Note: If you are using GatewayScript, you must include one or other of the following commands depending on your gateway type:
DataPower
Gatewayvar apic = require(./apim.custom.js);
DataPower API
Gatewayvar apic = require('apim');
where apic is the common name used for the GatewayScript examples in this topic. However, apic could be any given name of your choice, for example you could use:
var apim = require(./apim.custom.js);
and then you would start your calls with apim.

Access to input properties code snippet

The following code block shows an example of how to access the input properties by using the XSLT policyProperties() function. The example defines a property that is named a_property, which is declared as an integer value, but is retrieved in XSLT as text.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <xsl:variable name="p" select="apim:policyProperties()" />
    <xsl:message>
      The value of my input property is
      <xsl:value-of select="$p/a_property" />
    </xsl:message>
  </xsl:template>

</xsl:stylesheet>
If you are using GatewayScript, call the following function:
apic.getPolicyProperty(propertyName)
where propertyName is the name of the input property that you want to access. If the input property name is blank, the action will return all input properties.

Access to runtime context code snippet

The following code block shows an example of how to access the runtime context by using the XSLT getContext() function.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <xsl:variable name="client-id" select="apim:getContext('client.app.id')" />
    <xsl:message>
      The calling application is
      <xsl:value-of select="$client-id" />
    </xsl:message>
  </xsl:template>

</xsl:stylesheet>
If you are using GatewayScript, call the following function:
apic.getContext(varName)
where varName is the name of the context variable that you want to access.

For a complete list of context variables, see API Gateway context variables. If you are using the DataPower® API Gateway, see also Using context variables in GatewayScript and XSLT policies with the DataPower API Gateway.

Access to input payload code snippet

The following code block shows an example of how to access the input payload by using the XSLT payloadRead() function.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <xsl:variable name="input" select="apim:payloadRead()" />
    <xsl:message>
      The input payload is
      <xsl:copy-of select="$input" />
    </xsl:message>
  </xsl:template>

</xsl:stylesheet>
If you are using GatewayScript, call the following function:
apic.readInput(callback)
A callback is required because the actual payload read is asynchronous. The callback method is called when the payload is ready.
This function returns an XML node-set that contains the payload of the request. If the payload is in JSON format, a JSONx node-set is returned that can then be manipulated within an XSLT or GatewayScript stylesheet. If the payload is not in JSON or XML format, the node-set that is returned is empty.
The following example shows how to use the payloadType() function to determine what type of payload (XML or JSONx) will be returned by the XSLT payloadRead() function.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <xsl:variable name="payloadType" select="apim:payloadType()" />
    <xsl:message>
      <xsl:text>Payload type is [</xsl:text>
      <xsl:value-of select="$payloadType" />
      <xsl:text>]</xsl:text>
    </xsl:message>
  </xsl:template>

</xsl:stylesheet>

Access to HTTP headers code snippet

The following code block shows an example of how to access the HTTP headers in XSLT by using the getContext() function.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <xsl:variable name="content-type" select="apim:getContext('request.headers.content-type')" />
    <xsl:message>
      The request content type is
      <xsl:value-of select="$content-type" />
    </xsl:message>
  </xsl:template>

</xsl:stylesheet>
If you are using GatewayScript, call the following function:
apic.getContext(request.headers.headerName)
where headerName maps to the name of the header you want to access.
Note: Access or modification of HTTP headers by using DataPower extensions, such as dp:set-request-header, is not advisable, as such actions might yield unexpected results when the policy is combined with other policies and assembly steps.

Modify the payload code snippet

The output from a user-defined policy must be an XML node-set, which represents an XML or SOAP message, or a JSON message by using JSONx. The following code block shows an example of how to modify the payload in XSLT. To assist the API Gateway policy framework to accept the new or transformed message, call the apim-output template, as shown in the following example.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:apim="http://www.ibm.com/apimanagement"
  xmlns:jsonx="http://www.ibm.com/xmlns/prod/2009/jsonx">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <!-- Creates a JSON document (empty object is for simplicity) -->
    <jsonx:object>
    </jsonx:object>

    <!-- Indicates the media type of the output being produced -->

    <xsl:call-template name="apim:output">
      <xsl:with-param name="mediaType" select="'application/json'" />
    </xsl:call-template>
  </xsl:template>

</xsl:stylesheet>
where mediaType:
  • 'application/json' is when the output is written in JSONx format.
  • 'application/xml' is when the output is written in XML format.
If you are using GatewayScript, call the following function:
apic.output(mediaType)
where mediaType is:
  • application/json is when the output is written in JSONx format.
  • application/xml is when the output is written in XML format.

Specifying the media type allows the next steps in the assembly flow to understand how to process the new payload.

Tip: The output from a user-defined policy must be XML or JSONx. JSONx is an IBM standard format to represent JSON as XML. One way to convert output GatewayScript JSON data into JSONx, is to add a Convert Query Params to XML action to follow the GatewayScript action within the same policy rule. The Convert Query Params to XML action must have an Input Conversion with the Default Encoding set to JSON. The output from the GatewayScript action must be the input for the Convert Query Params to XML action for JSONx to be produced.

Configure error information code snippet

The following XSLT code block shows an example of how to configure the policy implementation to produce error information by calling the apim-error template.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:apim="http://www.ibm.com/apimanagement">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <!-- Indicates this policy has a failure and provides
       additional information for the client application -->
  <xsl:template match="/">
    <xsl:call-template name="apim:error">
      <xsl:with-param name="httpCode" select="'401'" />
      <xsl:with-param name="httpReasonPhrase" select="'Unauthorized'" />
      <xsl:with-param name="errorMessage" select="'Please select a Plan'" />
    </xsl:call-template>
  </xsl:template>

</xsl:stylesheet>
where:
  • httpCode is the code of the required error message.
  • httpReasonPhrase is the reason for the error.
  • errorMessage is the suggested action for the user.
If you are using GatewayScript, call the following function:
apic.error(name, httpCode, httpReasonPhrase, message)
where:
  • name is the name of the error.
  • httpCode is the code of the required error message.
  • httpReasonPhrase is the reason for the error.
  • message is the suggested action for the user.

Accessing the caught exception in a catch block

The following XSLT code block shows an example of how, in the catch block of an API assembly, you can obtain the details of the current caught exception. A possible use would be to create a custom error response using the details of the caught exception.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:dp="http://www.datapower.com/extensions" 
  DataPower
Gatewayxmlns:apim="http://www.ibm.com/apimanagement" 
  DataPower API
Gatewayxmlns:apigw="http://www.ibm.com/xmlns/datapower/2017/11/apigateway"  
  extension-element-prefixes="dp" 
  DataPower
Gatewayexclude-result-prefixes="dp apim"> 
  DataPower API
Gatewayexclude-result-prefixes="dp apim apigw"> 

  <xsl:output method="xml" />

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">

    DataPower
Gateway<xsl:variable name="exception" select="apim:getError()"/>
    DataPower API
Gateway<xsl:variable name="exception" select="apigw:get-error()"/>
    <!-- output desired error message based on the exception -->
    <myError>
       <errorReason><xsl:value-of select="$exception/error/message"/></errorReason>
    </myError>

    <!-- Propagate the HTTP status code and reason phrase from the exception -->       
    <xsl:call-template name="apim:setVariable">
      <xsl:with-param name="varName" select="'message.status.code'"/>
      <xsl:with-param name="value" select="$exception/error/status/code"/>
      <xsl:with-param name="action" select="'Set'" />
    </xsl:call-template>
              
    <xsl:call-template name="apim:setVariable">
      <xsl:with-param name="varName" select="'message.status.reason'"/>
      <xsl:with-param name="value" select="$exception/error/status/reason"/>
      <xsl:with-param name="action" select="'Set'" />
    </xsl:call-template>
       
    </xsl:template>

</xsl:stylesheet>
The apim:getError() and apigw:get-error() functions return an XML node set; for example:
<?xml version="1.0" encoding="UTF-8"?>
<error>
    <name>RuntimeError</name>
    <message>This is a thrown Runtime Error</message>
    <policyTitle>Throw Runtime Error</policyTitle>
    <status>
        <code>500</code>
        <reason>Internal Server Error</reason>
    </status>
</error>
If you are using GatewayScript, call the following function:
apim.getError()
which returns a JSON object; for example:
{
  "name": "OperationError",
  "message": "This is a thrown Operation Error",
  "policyTitle": "Throw Operation Error",
  "status": {
    "code": "500",
    "reason": "Internal Server Error"
  }
}

Set variables code snippet

The following XSLT code block shows an example of how to set a runtime variable to a specified string value by calling the setVariable template.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <xsl:call-template name="apim:setVariable">
      <xsl:with-param name="varName" select="'serviceEndpoint'" />
      <xsl:with-param name="value" select="'https://endpoint.host.com/data'" />
    </xsl:call-template>
    <xsl:message>
      <xsl:text>Variable [</xsl:text>
      <xsl:value-of select="'serviceEndpoint'" />
      <xsl:text>] set to [</xsl:text>
      <xsl:value-of select="'https://endpoint.host.com/data'" />
      <xsl:text>]</xsl:text>
    </xsl:message>
  </xsl:template>

</xsl:stylesheet>
where:
  • varName is the name of the runtime variable that you want to set a value to.
  • value is the string value that you want to set the variable to. This can be a literal value, or another variable. For example, to set your named variable to the value of the Content-Type header in a request, you would specify the value as $(request.headers.content-type).
If you are using GatewayScript, call the following function:
apic.setvariable(varName, varValue, action)
where:
  • varName is the name of the runtime variable that you want to set a value to, or that you want to add or clear.
  • varValue is the string value that you want to set the variable to. This can be a literal value, or another variable. For example, to set your named variable to the value of the Content-Type header in a request, you would specify the varValue as request.headers.content-type. This property is only required when set or add is specified as the action.
  • action is the action that you want to apply to the variable. Valid options are:
    • set
    • add
    • clear
    If no option is set, the default option of set is applied.
The following XSLT example shows how to retrieve the value of a runtime variable by using the getVariable() function.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim">

  <!-- Contains the APIM functions -->
  DataPower
Gateway<xsl:import href="local:///isp/policy/apim.custom.xsl" />
  DataPower API
Gateway<xsl:include href="store:///dp/apim.custom.xsl" />

  <xsl:template match="/">
    <xsl:variable name="varValue" select="apim:getVariable('serviceEndpoint')" />
    <xsl:message>
      <xsl:text>Variable [</xsl:text>
      <xsl:value-of select="'serviceEndpoint'" />
      <xsl:text>] = [</xsl:text>
      <xsl:value-of select="$varValue" />
      <xsl:text>]</xsl:text>
    </xsl:message>
  </xsl:template>

</xsl:stylesheet>
where
  • varValue is the name of the runtime variable that you want to retrieve a value for.
If you are using GatewayScript, call the following function:
apic.getvariable(varName)
where varName is the name of the runtime variable that you want to retrieve a value for.