Introduction

A common use case in API Management, is to tailor the API to the API consumer. For instance, you want to delete sensitive information before sending it to a business partner. There are multiple ways of doing this, but we will cover the case in which an XML OData REST Service needs to be stripped from specific information. We will do this by using XSL transformation features. This is also possible for JSON REST Services, however we would use JavaScript to modify the response.

The prerequisite for this tutorial, is that you are acquainted with SAP API Management, and that you have created the GWSAMPLE_BASIC API Proxy based on Holger Bruchelt’s document How to use SAP API Management on HCP Trial

Note that you can stop at the “Create product” chapter, since it will ease our tutorial (no api keys required for instance).

By the way: it is a good practice to version your API Proxy. To do so, you can add the version in the basepath. In that way, whenever you make structural changes to your API (eg. the request parameters or the response have changed), you can generate a new version of your proxy that will not disrupt the Apps using your first version of the API.

Last but not least: you may want to use a REST tool to test you API call. Postman is a very good and free tool, that has powerful basic functionalities, and can be extended with the purchase of specific licenses.

Overview

This tutorial will have 2 simple steps: adding an XSL Transform Policy, and adding the corresponding XSL file to the API Proxy resources. The XSL Transform Policy will actually call the XSL file as configured. For instance, instead of applying the transformation to the response, we could configure the XSL Transform policy to generate a new variable with the output of the transformation.

For this tutorial, we will use the ContactSet Resource from the GWSAMPLE_BASIC, and we will hide sensitive information such as Phone Numbers.

1- Add the XSL Transform policy

Just as with the JavaScript policy, the XSL Transform policy refers to an XSL File. It also tells the proxy how to apply the transformation.

To add the XSL Transform policy, open the Policy Designer by clicking on “Policies” from within your API.

Click on the “Edit” link on the right-bottom corner.

Click on the “ContactSet” conditional flow on the left-hand menu of the Policy Designer.

Click on the “+” sign next to the “XML Transform” policy, on the right-handed “Policies” panel.

Name: filterContactData

EndpointType and FlowType were set for you when you clicked on the “ProxyEndpoint>ContactSet” link in the previous step

Stream: Outgoing Response

Now, lets configure the policy.

In the XML policy configuration editor:

– delete the <OutputVariable>resp1</OutputVariable> node. In that way, the transformation is applied directly to the response, and not stored in a variable.

– modify the data of the ResourceURL in order to point to your XSL file (that we’ll add later):

<ResourceURL>xsl://filterContactDataXSL.xsl</ResourceURL>

Your policy configuration should look like this:

  1. <XSL async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
                    <!-- The XSLT file to be used for transforming the message. -->
                    <ResourceURL>xsl://filterContactDataXSL.xsl</ResourceURL>
                    <!-- Contains the message from which information needs to be extracted -->
                    <Source>response</Source>
    </XSL>

Be careful to enter the resource name we will add below correctly (right name and file extension): filterContactDataXSL.xsl

2- Add the XSL transformation file

To understand in detail what we will do, let’s have a look at the response of the ES4 System.

  1. <?xml version="1.0" encoding="utf-8"?>
    <entry xml:base="https://SAPES4.SAPDEVCENTER.COM:443/sap/opu/odata/iwbep/GWSAMPLE_BASIC/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
        <id>https://SAPES4.SAPDEVCENTER.COM:443/sap/opu/odata/iwbep/GWSAMPLE_BASIC/ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')</id>
        <title type="text">ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')</title>
        <updated>2016-08-24T08:01:20Z</updated>
        <category term="/IWBEP/GWSAMPLE_BASIC.Contact" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
        <link href="ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')" rel="edit" title="Contact"/>
        <link href="ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')/ToBusinessPartner" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ToBusinessPartner" type="application/atom+xml;type=entry" title="ToBusinessPartner"/>
        <content type="application/xml">
            <m:properties>
                <d:Address m:type="/IWBEP/GWSAMPLE_BASIC.CT_Address">
                    <d:City>Walldorf</d:City>
                    <d:PostalCode>69190</d:PostalCode>
                    <d:Street>Dietmar-Hopp-Allee</d:Street>
                    <d:Building>16</d:Building>
                    <d:Country>DE</d:Country>
                    <d:AddressType>02</d:AddressType>
                </d:Address>
                <d:ContactGuid>005056A2-16B8-1EE6-9AAF-1AFD8A856C2F</d:ContactGuid>
                <d:BusinessPartnerID>0100000000</d:BusinessPartnerID>
                <d:Title/>
                <d:FirstName>Karl</d:FirstName>
                <d:MiddleName/>
                <d:LastName>Müller</d:LastName>
                <d:Nickname/>
                <d:Initials/>
                <d:Sex>M</d:Sex>
                <d:PhoneNumber>0622734567</d:PhoneNumber>
                <d:FaxNumber>0622734004</d:FaxNumber>
                <d:EmailAddress>do.not.reply@sap.com</d:EmailAddress>
                <d:Language>EN</d:Language>
                <d:DateOfBirth m:null="true"/>
            </m:properties>
        </content>
    </entry>

As you can see, there are two nodes containing phone numbers: PhoneNumber andFaxNumber. We will remove these numbers using an XSL Transformation.

The following XSL code is based on the Identity Transform pattern. It will copy the payload whilst omitting the nodes specified in the “template”. In our case, we’ll remove the PhoneNumber and FaxNumber.

Note that we also added the default namespace in the xsl:stylesheet configuration.

  1. <?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="http://schemas.microsoft.com/ado/2007/08/dataservices">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>
    <xsl:template match="PhoneNumber|FaxNumber"/>
    </xsl:stylesheet>

Now we’ll add  a resource file to our proxy, containing the code above, to be used by the XSL Transform policy.

To do so, open the Policy Designer by clicking on “Policies” from within your API.

Click on the “Edit” link in the bottom-right corner.

Click on the “+” sign next to the “Scripts” section on the left side of the Policy Designer.

In the window that comes up, enter the name of the XSL resource, for instancefilterContactDataXSL.

Select the type to be XSL.

Click on Add.

Now click on the resource to edit it:

In the script editor, paste the XSL code from above.

Click on update and save your API proxy.

Now, let’s test your proxy. To do so, use either Chrome or Postman, and use the following URL:

<YourProxyBasePath>/ContactSet(guid’005056A2-16B8-1EE6-9AAF-1AFD8A856C2F’)

The result does not contain any of the nodes we filtered out in the XSL file: PhoneNumber and FaxNumber have been removed!

  1. <?xml version="1.0" encoding="UTF-8"?>
    <entry xmlns="http://www.w3.org/2005/Atom"
           xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
           xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
           xml:base="https://SAPES4.SAPDEVCENTER.COM:443/sap/opu/odata/iwbep/GWSAMPLE_BASIC/">
        <id>https://SAPES4.SAPDEVCENTER.COM:443/sap/opu/odata/iwbep/GWSAMPLE_BASIC/ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')</id>
        <title type="text">ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')</title>
        <updated>2016-08-24T12:57:12Z</updated>
        <category term="/IWBEP/GWSAMPLE_BASIC.Contact"
                 scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
        <link href="ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')"
             rel="edit"
             title="Contact"/>
        <link href="ContactSet(guid'005056A2-16B8-1EE6-9AAF-1AFD8A856C2F')/ToBusinessPartner"
             rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ToBusinessPartner"
             type="application/atom+xml;type=entry"
             title="ToBusinessPartner"/>
        <content type="application/xml">
            <m:properties>
                <d:Address m:type="/IWBEP/GWSAMPLE_BASIC.CT_Address">
                    <d:City>Walldorf</d:City>
                    <d:PostalCode>69190</d:PostalCode>
                    <d:Street>Dietmar-Hopp-Allee</d:Street>
                    <d:Building>16</d:Building>
                    <d:Country>DE</d:Country>
                    <d:AddressType>02</d:AddressType>
                </d:Address>
                <d:ContactGuid>005056A2-16B8-1EE6-9AAF-1AFD8A856C2F</d:ContactGuid>
                <d:BusinessPartnerID>0100000000</d:BusinessPartnerID>
                <d:Title/>
                <d:FirstName>Karl</d:FirstName>
                <d:MiddleName/>
                <d:LastName>Müller</d:LastName>
                <d:Nickname/>
                <d:Initials/>
                <d:Sex>M</d:Sex>
                <d:EmailAddress>do.not.reply@sap.com</d:EmailAddress>
                <d:Language>EN</d:Language>
                <d:DateOfBirth m:null="true"/>
            </m:properties>
        </content>
    </entry>

Conclusion

As you could experience for yourself, filtering out data from a service is pretty easy. Also, we did not use any fancy proprietary format, but only something that has been around for years, XSL.

In this example, we used an OData service talking XML. To do the same for a service talking JSON, we would use a JavaScript policy since JSON can be manipulated in a very easy and efficient way with JavaScript.

I hope you enjoyed this tutorial, and feel free to give your feedback through the comments!

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply