Implementing advanced transformations with XSLT and GatewayScript – Digital Transformation with IBM API Connect

So, you find yourself needing to perform a transformation on your messages, but none of the built-in transformation policies will provide exactly what you need. Perhaps you don’t want to transform your messages to a different structure, but you wanted to add to, or enrich, your messages. Or maybe you want to encrypt a specific field instead of redacting it. Countless transformation use cases may present themselves with each one being similar, but different enough that they will require some custom coding. This is where API Connect provides the ability to utilize two powerful programming languages to give you the flexibility to customize your transformations in any way you would like. In this section, we will discuss a few scenarios where this would be helpful, but the possibilities are endless when you have the ability to get back to the power and control of basic programming!

XSLT

Extensible Stylesheet Transformation Language (XSLT) literally has “transformation” in the name! XSLT is a language that is specifically designed to transform XML documents into other XML documents. So, if you are looking for a more complex XML to XML transformation where you have more programmatic control, this one is your go-to. XSLT is also considered a Turing-complete programming language, which basically means that it can perform any calculations and computations that can be performed by modern programming languages. Hence, in a nutshell, you have here a complete programming language that is also specifically designed to transform XML documents. If that was good enough, your Gateway service that will be executing the XSLT is most likely going to be DataPower, which, from the beginning, was optimized to execute XSLT transformations.

If you have worked with the DataPower product line, you are most likely very familiar with XSLT and how to write a basic XML to XML transformation. If you are not familiar with XSLT, it would behoove you to become familiar with it so that you can take advantage of this capability with API Connect. You can find plenty of tutorials and information on the web, as well as several books available on the topic. Instead of covering the fundamentals of the XSLT language, we will focus on some more advanced and API Connect-specific features, such as accessing API Connect variables and EXSLT extension functions, which are also supported.

To demonstrate some of the features available to us in our XSLT policy, let’s take our simple createOrder request XML message. Perhaps we have a requirement to enrich this XML with a timestamp, the host header that came in on the request, and we require a total count of the items sent. This can easily be accomplished within the XSLT policy by utilizing simple XSLT, an EXSLT extension function, and an API Connect function to access the custom variables.

Before writing your XSLT, you will need to drag the XSLT onto the Gateway policy pane, as you did with the other policies. Once your policy is in place, a configuration screen will appear with an editor where you can write your XSLT code. You will also notice a checkbox to indicate whether the input context for this policy should be used as the input to the XSLT. Checking this box indicates that it will be. For our example, we will be using the input context to create our output XML document, so we will check this box. The editor provided is not all that big and would be difficult to code in in the current state. Clicking the double arrows at the top right of the configuration will expand the configuration screen, making the editor much bigger. Other than the one checkbox, there aren’t any other configuration options for this policy other than the code itself, so let’s dive into that:

<xsl:stylesheet version=”1.0″

xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”

xmlns:date=”http://exslt.org/dates-and-times”

xmlns:apim=”http://www.ibm.com/apimanagement”>

<!—-Use for V5 compatible gateway –>

<xsl:import href=”local:/isp/policy/apim.custom.xsl”/>

<!– Use for API gateway

<xsl:include href=”store:///dp/apim.custom.xsl” />

–>

<xsl:template match=”/”>

<createOrder>

<requestHost>

<xsl:value-of select=

“apim:getVariable(‘request.headers.host’)”/>

</requestHost>

<timestamp><xsl:value-of select=”date:date-

time()”/></timestamp>

<customerId><xsl:value-of select=

“createOrder/customerId”/></customerId>

<xsl:for-each select=”createOrder/items”>

<items>

<itemNumber><xsl:value-of select=

“itemNumber”/></itemNumber>

<itemQuantity><xsl:value-of select=

“itemQuantity”/></itemQuantity>

<itemDescription><xsl:value-of select=

“itemDescription”/></itemDescription>

</items>

</xsl:for-each>

<orderTotal><xsl:value-of select=

“createOrder/orderTotal”/></orderTotal>

<itemCount><xsl:value-of select=

“count(createOrder/items)”/></itemCount>

</createOrder>

</xsl:template>

</xsl:stylesheet>

Let’s take a closer look at this stylesheet and the parts that are not basic XSLT.

To start with, take note of the namespace declarations and you will notice that in addition to the standard xsl namespace declarations, we also declare the date and apim namespaces. The date namespace is declared so we can use the EXSLT dates and times’ elements and functions. The apim namespace is declared, so we can use the API Connect-specific elements and functions.

To use the API Connect built-in functions, we must use the xsl:import directive to import the XSLT provided with the product. Notice that this will be different if your gateway is configured for V5 compatibility versus an API gateway.

As we proceed through the XSLT, we have our standard template definition and we start our output XML document. You can see that our first element after the root element is named <requestHost>. This is where we want to use the host header that came in on the request to populate this element. For this, we use a built-in API Connect function, getVariable. You can identify this as such by the apim namespace. This is a very powerful function that provides you with access to all of the API Connect context variables as well as the API property variables. For more information on the specific variables available, please refer to the IBM Info Center at https://www.ibm.com/support/knowledgecenter/SSMNED_v10/com.ibm.apic.toolkit.doc/capim_context_references.html.

In our example, we are retrieving the request.headers.host context variable, which will contain the value of a request header sent in the request with the name host.

The next element in our transformed request XML will be timestamp. As its name implies, this will be the current date and time that the XSLT is executed. This is retrieved using the EXSLT function, date-time().

The remainder of our XSLT is standard XSLT functionality, where you can see that we loop through each items element using the for-each statement. Finally, we use the XSLT count() function to return the number of items elements in the request.

This completes our simple, yet effective XSLT. You can see a sample request and response in Figure 8.20:

Figure 8.20 – XML request transformed via XSLT

Although we are only scratching the surface here with the power of XSLT, EXSLT, and API Connect functions, we demonstrated in one simple stylesheet at least one useful component of each. Since you have the power of a complete programming language, the possibilities are endless. It is important, however, to keep in mind that XSLT is designed and optimized to process XML. So, when your transformation consists of only XML, this should be your go-to transformation language. Once you start introducing other formats such as JSON, you might then want to consider another language that is both supported on API Connect and better optimized for other message formats. That would be GatewayScript, which will cover in the final section of this chapter.

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *