SAP API Management & HANA XS - Part IV
Sandro Montemezzani - 01.04.2019Überblick
![](/cms/media/Screenshot_2019-03-28_API_Portal.png)
In diesem Teil der Blog-Serie erweitern wir das Szenario um eine API-Schnittstelle zu den Daten. Hierzu verwenden wir das API-Management auf der SAP Cloud Platform.
Wir erstellen zunächst eine neue API im API Portal, wie auf dem Bild zu sehen ist.
Die API wird einen API-Key zum Zugriff benötigen, welcher als Header APIKey
mitgeliefert wird.
API Designer
![](/cms/media/Screenshot_2019-03-28_SAP_API_Designer.png)
Die Endpunkte zur API definieren wir mit dem API Designer von SAP. Hierzu kann auf der Seite zur neu angelegten API auf "Edit in API Designer" geklickt werden.
Im API-Designer werden die Endpunkte im YAML Format nach OpenAPI Spezifikation definiert. Mehr Informationen zur OpenAPI Spezifikation gibt es hier.
swagger: '2.0'
info:
version: '1'
title: Company Data
description: '<p>Company Data</p>'
host: 'pXXXXXXXXXXtrial-trial.apim1.hanatrial.ondemand.com:443'
basePath: /companydata/v1
produces:
- application/json
consumes:
- application/xml
schemes:
- https
paths:
/companies:
get:
parameters:
- name: APIKey
in: header
description: the API key that is provided by the developer portal
type: string
required: true
description: lists all companies in the database
responses:
'200':
description: Success
schema:
type: array
items:
type: object
properties:
id:
type: integer
key:
type: string
long_name:
type: string
short_name:
type: string
...
Folgende Endpunkte werden für unser Szenario benötigt:
/companies
- Listet alle Companies in der Datenbank/companies/{CompanyId}
- Gibt eine bestimmte Company zurück/entities
- Listet alle Entities in der Datenbank, optional gefiltert mit einem type Parameter/entities/{entityId}
- Gibt eine bestimmte Entity zurückWiederverwendung von Services/entities/{entityId}/hours
- Listet die Öffnungszeiten dieser Entity zwischen from und until Parametern/entities/{entityId}/hours/{weekOfYear}
- Listet die Öffnungszeiten für die zB zwanzigste Kalenderwoche
API Policies
![](/cms/media/Screenshot_2019-03-28_Verify_API_Key.png)
![](/cms/media/Screenshot_2019-03-28_Backend_Authentication.png)
![](/cms/media/Screenshot_2019-03-28_Set_Target_Company_Id.png)
Die Policies der API sollen zum einen sicherstellen, dass der API-Aufruf zusammen mit einem gültigen API-Key getätigt wurde. Darüber hinaus sollen sie den API-Aufruf in einen gültigen OData-Query umwandeln und die für die Datenbank benötigten Credentials einfügen.
Für die APIKey-Validierung können wir die vorgefertigte Policy "Verify API Key" zum Incoming-Request-Stream des Proxy-Endpoint-Preflows einfügen:
<VerifyAPIKey async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<APIKey ref="request.header.APIKey" />
</VerifyAPIKey>
Für die Backend-Credentials fügen wir zunächst eine "Assign Message" Policy zum Incoming-Request-Stream des Target-Endpoint-Postflows hinzu, und fügen die entsprechenden Daten für den COMPANYDATAUSER_READONLY
Nutzer ein:
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<AssignVariable>
<Name>backend_username</Name>
<Value>COMPANYDATAUSER_READONLY</Value>
</AssignVariable>
<AssignVariable>
<Name>backend_password</Name>
<Value>*********</Value>
</AssignVariable>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignTo createNew="false" type="request"></AssignTo>
</AssignMessage>
gefolgt von einer "Basic Authentication"-Policy:
<BasicAuthentication async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<Operation>Encode</Operation>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<User ref='backend_username'></User>
<Password ref='backend_password'></Password>
<AssignTo createNew="false">request.header.Authorization</AssignTo>
</BasicAuthentication>
Im Proxy-Endpoint wurden einige Conditional-Flows automatisch generiert. Diese replizieren wir für den Target-Endpoint. Dies ist nötig da einige interne Variablen beim Sprung vom Proxy-Endpoint auf den Target-Endpoint zurückgesetzt werden.
In diese Conditional-Flows fügen wir nun Policies zum extrahieren der Variablen ein und gegebenenfalls zum umschreiben der URL für einen gültigen OData-Call. Für das Beispiel /companies/{CompanyId}
sähe das folgendermaßen aus:
Zunächst fügen wir eine "Extract Variables"-Policy auf den Incoming-Request-Stream ein mit:
<ExtractVariables async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<URIPath>
<Pattern ignoreCase="true">/companies/{CompanyId}</Pattern>
<Pattern ignoreCase="true">/companies/{CompanyId}/</Pattern>
</URIPath>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</ExtractVariables>
gefolgt von einer Javascript-Policy:
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" xmlns="http://www.sap.com/apimgmt">
<ResourceURL>jsc://set_target_company_id.js</ResourceURL>
</Javascript>
mit der dazugehörigen Script-Datei set_target_company_id.js
:
var target_schemehostport = "https://hanapXXXXXXXXXXtrial.hanatrial.ondemand.com";
var target_basepath = context.getVariable("target.basepath");
var company_id = context.getVariable("CompanyId");
var target_base = target_schemehostport + target_basepath;
var target_url = target_base + "/companies(" + decodeURI(company_id) + ")";
context.setVariable("target.url", encodeURI(target_url));
API Testen
Bevor die API getestet werden, muss sie noch Veröffentlicht werden. Im API-Portal muss ein Produkt erstellt werden, welches diese API beinhaltet. Den API-Key erhält man durch erstellen einer Applikation im Developer Portal, welche dieses Produkt abonniert.
Nun kann die API mit folgendem Befehl getestet werden:
$ curl -sH "APIKey: *********" https://pXXXXXXXXXXtrialtrial.apim1.hanatrial.ondemand.com/p2000572343trial/companydata/v1/companies/0 |xmllint --format -
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom" xml:base="https://hanapXXXXXXXXXXtrial.hanatrial.ondemand.com:443/companydata/CompanyData.xsodata/">
<id>https://hanapXXXXXXXXXXtrial.hanatrial.ondemand.com:443/companydata/CompanyData.xsodata/companies(0)</id>
<title type="text"/>
<author>
<name/>
</author>
<link rel="edit" title="companies" href="companies(0)"/>
<category term="companydata.companiesType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<content type="application/xml">
<m:properties>
<d:id m:type="Edm.Int32">0</d:id>
<d:key m:type="Edm.String">SMTH</d:key>
<d:long_name m:type="Edm.String">Smith Craftings LLC</d:long_name>
<d:short_name m:type="Edm.String">SmithCraft</d:short_name>
</m:properties>
</content>
</entry>
Schlusswort
Das war die Blog-Serie zu einem vollständigen API-Management Szenario in der SAP HANA XS. Die Daten können nun von außen aus über die API-Schnittstelle zugegriffen werden. Ein nächster Schritt wäre zum Beispiel, diese Daten über ein SAPUI5-Interface abrufbar zu machen.
- Zum vorherigen Part: Part III - HANA XS - oData Services