Technical Articles
HERE Location Services with SAP API Management and Kyma functions
Seamlessly integrate location intelligence into SAP LOBs with SAP API Management and Kyma functions
The task here is to implement HERE Location Services with SAP API Management and Kyma functions HERE Location Services APIs are available on SAP API Business Hub. With SAP APIM one can copy HERE APIs directly from the API Business Hub and create her/his own managed versions of HERE APIs endpoints within the SAP integration suite framework. |
Pre-requisites:
|
Disclaimer:
|
Putting it all together
STEP | HOW |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
For instance let’s get a seven days weather forecast for New York:
https://<APIM domain>.hana.ondemand.com/theta/weather/1.0/report.json?product=forecast_7days_simple&name=new%20york
{
"dailyForecasts": {
"forecastLocation": {
"forecast": [
{
"daylight": "D",
"description": "Sunny. Cool.",
"skyInfo": "1",
"skyDescription": "Sunny",
"temperatureDesc": "Cool",
"comfort": "11.64",
"highTemperature": "14.00",
"lowTemperature": "1.60",
"humidity": "69",
"dewPoint": "6.81",
"precipitationProbability": "1",
"precipitationDesc": "",
"rainFall": "*",
"snowFall": "*",
"airInfo": "*",
"airDescription": "",
"windSpeed": "8.28",
"windDirection": "270",
"windDesc": "West",
"windDescShort": "W",
"beaufortScale": "2",
"beaufortDescription": "Light breeze",
"uvIndex": "0",
"uvDesc": "Minimal",
"barometerPressure": "1022.58",
"icon": "1",
"iconName": "sunny",
"iconLink": "https://weather.ls.hereapi.com/static/weather/icon/1.png",
"dayOfWeek": "2",
"weekday": "Monday",
"utcTime": "2021-11-08T00:00:00.000-05:00"
},
{
...............(truncated)...................................
}
],
"country": "United States",
"state": "New York",
"city": "New York",
"latitude": 43.00035,
"longitude": -75.4999,
"distance": 0,
"timezone": -5
}
},
"feedCreation": "2021-11-08T21:02:07.902Z",
"metric": true
}
and the map image:
https://<APIM domain>.hana.ondemand.com/theta/mia/1.6/mapview?ci=New%20York&co=USA&h=600&q=85&w=800
Conclusion
I hope you have enjoyed the demo of HERE Location Services.
After I have worked out all the steps APIM allowed me to cut the development time to merely minutes (for each new API service that I wanted to bring to life).
The most complex bit was to create a signed user JWT bearer access token that needs to be passed in the Authorization header of each of HERE Location Service API calls. Initially I wanted to implement the token generation entirely within APIM but eventually I decided to offload this task to a backend kyma function (cf. appendix below).
The APIM policy takes care of the bearer access token caching and will invalidate it every hour (even if the token itself is valid for 24 hours). Furthermore, the APIM managed API endpoints can be packed into a product and protected with Oauth2.0 access token if that was required.
Last but not least, because HERE Location Services APIs are being called via a so-called API proxy the Authorization header with the bearer access token is nowhere to be seen.
HERE Location Services are now ready to use with the likes of SAP WorkZone, Launchpad Service, SAP Appgyver or in any bespoke HTML5 application…
Appendix
a. The Kyma nodejs backend function to generate the user JWT token
//----------------------------------------------------------------------------------------
const axios = require('axios')
const qs = require('qs')
const OAuth = require('oauth-1.0a') // https://github.com/ddo/oauth-1.0a
const crypto = require('crypto') // https://nodejs.org/en/knowledge/cryptography/how-to-use-crypto-module/
//----------------------------------------------------------------------------------------
//
function hash_function_sha256(base_string, key) {
return crypto
.createHmac('sha256', key)
.update(base_string)
.digest('base64')
}
//----------------------------------------------------------------------------------------
// https://developer.here.com/documentation/identity-access-management/dev_guide/topics/sdk.html
// Token request function
//
async function generateHEREToken(event) {
// #1 Initialize OAuth with your HERE OAuth credentials from your HERE project space
const oauth = OAuth({
consumer: {
key: '<Access key>', //Access key
secret: '<Secret key>', //Secret key
},
signature_method: 'HMAC-SHA256',
hash_function: hash_function_sha256,
});
// https://stackoverflow.com/questions/61534012/here-map-api-request-token-with-nodejs
// #2 Building the request object.
const request_data = {
url: 'https://account.api.here.com/oauth2/token',
method: 'POST',
data: { grant_type: 'client_credentials' }
};
const headers = oauth.toHeader(oauth.authorize(request_data));
console.log (headers);
let documents;
// #3 Sending the request to get the access token
try {
const response = await axios.post(request_data.url,qs.stringify(request_data.data),{ withCredentials: true, headers: {'Authorization': headers.Authorization } });
console.log(JSON.stringify(response.data, null, 2));
console.log(response.status);
return response.data;
}
catch(error) {
documents = JSON.stringify(error, null, 2);
console.log(error);
};
return documents;
}
- here goes the entry point of a kyma serverless function
module.exports = {
main: async function (event, context) {
switch (event.extensions.request.path) {
case '/here_token2': {
return generateHEREToken(event);
}
}
}
}
Last but not least. Here goes the function’s response payload:
{
"access_token": "eyJhbGciOiJSUzUxMiIsImN0eSI6IkpXVCIsImlzcyI6IkhFUkUiLCJhaWQiOiJkanZuR3BOWHpiRGhLZHY3bnR5eSIsImlh
.................................(truncated)..................................................
YKl14kxe425T4HMhcBopWpTJWU9us5TvImzUBDTzkcTd_G8dyQ",
"token_type": "bearer",
"expires_in": 86399
}
As the above function call will be called from APIM service callout policy (cf code snippet below), it will need to be exposed to the public internet via an API rule kyma mechanism.
Good to know:
- kyma serveless functions are intrinsic to current SAP Kyma runtime offering thus there is no separate charge for kyma functions invocations.
b. The APIM service callout policy
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<Request clearPayload="true">
<Set>
<Verb>GET</Verb>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<Response>sapapim.tokenresponse</Response>
<Timeout>30000</Timeout>
<HTTPTargetConnection>
<URL>https://<API RULE>.kyma.shoot.live.k8s-hana.ondemand.com/here_token2</URL>
</HTTPTargetConnection>
</ServiceCallout>
Additional resources
OAuth 1.0a Request Authorization | Github Creating OAuth 1.0 Signature with SCP API Portal | SAP Blogs OAuth 1.0a Authorization Tutorial | SAP Jam Collaboration Developer Guide | SAP Help Welcome to SAP API Business Hub Community for API Recipes | Githhub Developer resources:
|