Implementation code examples
Example code snippets to help the creation of a user-defined policy implementation.
Note: If you are using GatewayScript, you must include the following
command:
var apic = require(./apim.custom.js);
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 XSLTpolicyProperties()
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"
exclude-result-prefixes="dp func apim"
extension-element-prefixes="dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" /> <!-- Use this import for XSLT 1.0.0 only (v5c Gateway) -->
<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" />
<apigw:set-variable name="'propfound'" value="'true'"/>
</xsl:message>
</xsl:template>
</xsl:stylesheet>
If you are using GatewayScript, you must call the
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 XSLTgetContext()
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"
exclude-result-prefixes="dp func apim"
extension-element-prefixes="dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" /> <!-- Use this import for XSLT 1.0.0 only (v5c Gateway) -->
<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, you must call the
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.
Access to input payload code snippet
The following code block shows an example of how to access the input payload by using the XSLTpayloadRead()
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"
exclude-result-prefixes="dp func apim"
extension-element-prefixes="dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" /> <!-- Use this import for XSLT 1.0.0 only (v5c Gateway) -->
<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, you must call the
function:
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.apic.readInput(callback)
A callback is required because the actual
payload read is asynchronous. The callback method is called when the payload is ready.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"
exclude-result-prefixes="dp func apim"
extension-element-prefixes="dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" /> <!-- Use this import for XSLT 1.0.0 only (v5c Gateway) -->
<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 thegetContext()
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"
exclude-result-prefixes="dp func apim"
extension-element-prefixes="dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" /> <!-- Use this import for XSLT 1.0.0 only (v5c Gateway) -->
<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, you must call the
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 theapim-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"
exclude-result-prefixes="apim"
extension-element-prefixes="apim">
<!-- Contains the APIM functions -->
<xsl:include href="local:///isp/policy/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, you must call the
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 theapim-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"
exclude-result-prefixes="apim"
extension-element-prefixes="apim">
<!-- Contains the APIM functions -->
<xsl:include href="local:///isp/policy/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, you must call the template:
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.
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 thesetVariable
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"
exclude-result-prefixes="dp func apim"
extension-element-prefixes="dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" /> <!-- Use this import for XSLT 1.0.0 only (v5c Gateway) -->
<xsl:template match="/">
<xsl:variable name="" select="'https://endpoint.host.com/data'" />
<xsl:call-template name="apim:setVariable">
<xsl:with-param name="varName" select="'serviceEndpoint'" />
<xsl:with-param name="value" select="$targetUrl" />
<xsl:with-param name="action" select="'set'" />
</xsl:call-template>
<xsl:message>
<xsl:text>Variable [</xsl:text>
<xsl:value-of select="'serviceEndpoint'" />
<xsl:text>] = [</xsl:text>
<xsl:value-of select="$targetUrl" />
<xsl:text>]</xsl:text>
</xsl:message>
<dp:url-open target="{$targetUrl}" response="xml" http-method="get"/>
</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 thevalue
as$(request.headers.content-type)
.
If you are using GatewayScript, you must call the template:
The following XSLT example shows how to retrieve the value of a runtime variable by using
the 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 thevarValue
asrequest.headers.content-type
. This property is only required whenset
oradd
is specified as the action.action
is the action that you want to apply to the variable. Valid options are:set
add
clear
set
is applied.
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"
exclude-result-prefixes="dp func apim"
extension-element-prefixes="dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" /> <!-- Use this import for XSLT 1.0.0 only (v5c Gateway) -->
<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>
<dp:url-open target="{$varValue}" response="xml" http-method="get"/>
</xsl:template>
</xsl:stylesheet>
wherevarValue
is the name of the runtime variable that you want to retrieve a value for.
If you are using GatewayScript, you must call the
function:
apic.getvariable(varName)
where
varName
is the name of the runtime variable that you want to
retrieve a value for.