Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Now that SAP API Management is available on HCP Trial we already can see quite a lot of people using it.

So far we have covered topics like Policy handling, URL masking and much more content is on its way. As of now we talked mainly about how to consume OData services or how to pass-through SOAP calls. In this blog I want to outline how you can connect to a SOAP service and expose it as REST.

The beautity of this approach is that developers who want to consume the service do not have to struggle with creating a correct SOAP envelope, find out the correct structure on how to retrieve the information, ...

Instead we can completely rely on REST attributes: we can use simple GET parameters to query something and could also implement PUT and POST methods to actually update information.

Recently we used a SOAP service for a Credit Check in a customer project which worked extremly well. The complexity of the SOAP structure was hidden behind a simple REST call. Unfortunately this service is not public so for this blog I have to fall back to a simple GeoIP service. This service takes an IP address and returns the details of the Country Name and Country Code.

GeoIPService Web Service

You can find more information and details here:

http://www.webservicex.net/New/Home/ServiceDetail/64


The typical payload for this service looks like this:


POST /geoipservice.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.webservicex.net/GetGeoIP"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
  <GetGeoIP xmlns="http://www.webservicex.net/">
  <IPAddress>string</IPAddress>
  </GetGeoIP>
  </soap:Body>
</soap:Envelope>






and as a result you would get something like this:


HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
  <GetGeoIPResponse xmlns="http://www.webservicex.net/">
  <GetGeoIPResult>
  <ReturnCode>int</ReturnCode>
  <IP>string</IP>
  <ReturnCodeDetails>string</ReturnCodeDetails>
  <CountryName>string</CountryName>
  <CountryCode>string</CountryCode>
  </GetGeoIPResult>
  </GetGeoIPResponse>
  </soap:Body>
</soap:Envelope>






The goal of this blog is now to reduce the input of service to something simple as


/v1//ipinfo/?ip={adress}

and have an equaly simple response like


{"ReturnCode":1,"IP":"String","ReturnCodeDetails":"String","CountryName":"String","CountryCode":"String"}

So lets get started.


At first we need to create a new API Proxy. Since we will connect directly to this specific service we do not have to create a seperate System. Instead we will just specify the URL and define the API Base Path.


So go to your HCP Trial -> SAP API Management subscription -> click on Manage and -> Create (see How to use SAP API Management on HCP Trial) for more details.



In the Proxy details page you can just click on Save to save the API Proxy:


Now we have to do the mapping. This will be done via the Policy Designer. Go to the 4th icon and click on the Launch Policy Designer:

Extract IP-Address

Assuming that we want the developer to call the URL


/v1/ipinfo/?ip=123123

we need to first extract the IP information. For this click on Edit, then PreFlow on the left hand side and finally the Policy "Extract Variables" on the left.


In the Create Policy screen enter the name

extractIPAddress

and leave the Stream as "Incoming Request"

Then click on Add



In order to retrieve the query parameter "ip" change / replace the content with this information


<!-- Extract content from the request or response messages, including headers, URI paths, JSON/XML payloads, form parameters, and query parameters -->
<ExtractVariables async="true" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
  <QueryParam name="ip">
        <Pattern ignoreCase="true">{IPAddress}</Pattern>
    </QueryParam>
     <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</ExtractVariables>





In line 03 we look for the query parameter ip and assign it in line 04 to the variable {IPAddress}


Create SOAP Request

With that we can create the SOAP request which we can send to the actual service.


For this click again on the PreFlow on the left and select the "Assign Message" Policy on the right. Now enter a name

setSOAPRequest

for the new Policy.


In the editor we can replace / enhance the content with the following.


<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
  <!-- Sets SOAP request header, payload and method to POST -->
  <Set>
        <Headers>
            <Header name="Content-Type">application/soap+xml; charset=utf-8</Header>
        </Headers>
        <Payload contentType="text/xml">
            <soap:Envelope
                xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <soap:Body>
                    <GetGeoIP
                        xmlns="http://www.webservicex.net/">
                        <!--Optional-->
                        <IPAddress>{IPAddress}</IPAddress>
                    </GetGeoIP>
                </soap:Body>
            </soap:Envelope>
        </Payload>
        <Verb>POST</Verb>
    </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>





In this AssignMessage Policy we set the header in line 07, and then put the Payload exactly like the SOAP Service is looking for. For the parameter <IPAddress> we add the variable {IPAddress} which we extracted in the set before.



Response from the Service -> XML to JSON

Once we do this call to the service, we will get back a SOAP reply. This is nice, but we actually want to return data in JSON format. So we need to convert the XML SOAP response to JSON. In order to do that, make sure that you select the PreFlow from the TargetEndpoint and click on XML to JSON:



In the Create Policy windows enter a name

convertToJSON

and select

Outgoing Response

from the Stream drop-down



In this policy we can replace / edit the content to



<!-- This policy converts an XML payload to JSON structure -->
<XMLToJSON async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
  <Options>
  </Options>
  <!-- The variable to which the converted JSON should be assigned to -->
  <OutputVariable>response</OutputVariable>
  <!-- The variable that we want to convert to JSON -->
  <Source>response</Source>
</XMLToJSON>





Basically what we are doing here is taking response from the service (Line 08) and put it back as JSON (Line 06)

Simplify JSON response

The final step is that we want to reduce the response and only return some portions of it. In order to do that, make sure that you have still the TargetEndpoint -> PreFlow selected on the right hand, and select Extract Variables on the left hand side. In this new policy enter the name

extractResponse

while making sure that you have the Outgoing Response selected from the drop-down



The response that we would get so far is something like that:


{"Envelope":
  {"Body":
  {"GetGeoIPResponse":
  {"GetGeoIPResult":
  {"ReturnCode":"1",
  "IP":"172.16.254.1",
  "ReturnCodeDetails":"Success",
  "CountryName":"Reserved",
  "CountryCode":"ZZZ"}
  }
  }
  }
}





What we want is only the part from the GetGeoIPResult. So edit / replace the content of the policy with this:


<!-- Extract content from the request or response messages, including headers, URI paths, JSON/XML payloads, form parameters, and query parameters -->
<ExtractVariables async="true" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
  <!-- the source variable which should be parsed -->
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
  <JSONPayload>
        <Variable name="soapresponse">
            <JSONPath>$.Envelope.Body.GetGeoIPResponse.GetGeoIPResult</JSONPath>
        </Variable>
    </JSONPayload>
    <Source>response</Source>
</ExtractVariables>





Here we look at the content from the response (line 10), extract the path Envelope.Body.GetGeoIPResponse.GetGeoIPResult (line 07) and put it in the variable soapresonse (line 06).



Set the response

That's almost it. Now we only have to put the soapresponse back in the actual response. So again, make sure that you have the TargetEndpoint -> PreFlow selected, click on Assign Message on the left and enter a name

setResponse

for the new Policy while making sure you have the Outgoing Response selected

In the editor we will edit / replace the content to:


<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
  <!-- Sets the converted json to the response -->
  <Set>
  <Payload contentType="application/json">{soapresponse}</Payload>
  </Set>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <AssignTo createNew="false" type="response">response</AssignTo>
</AssignMessage>





In line 06 we set the payload to {soapresponse} -- the variable we extracted in the previous step -- and that is it!

Testing

Now we are ready to test the API. Make sure you click on Update and Save when exiting the Policy Editor.

Now if you go to the Test Console you can select the IPInfo API, add an IP address, select Get and fire your request:

As a result you get an easy to consume response 🙂

---

Update: for more information see SAP API Management - Overview & Getting started

4 Comments