Open your SAP OData APIs for some swagger – or how to make friends with the other kids from the API block
|📢Note: Before implementing data extraction or write back to/from SAP systems please verify your licensing agreement. SAP Principal Propagation eases that hurdle for read operations.|
Me and Will Eastbury have been busy building upon the work of the Oasis Foundation in the OData + OpenAPI space, where SAP and Microsoft are large contributors. Today is the day of easily converting your OData metadata into the widely spread OpenAPI definition and making that available to external consumers. Hence, opening your platform to a wide eco system of APIs and developer expertise. 🌎 This becomes more and more relevant due to SAP’s initiative to “keep the ABAP core clean”, “side-by-side-extension” pattern and the race for developers.
We will walk you through the steps using the SAP Gateway hosted OData service GW_SAMPLE_BASIC exposing it to Microsoft Power Automate as a connector to prove the point. SAP Gateway is available for ECC and S/4HANA by the way.
Cherry on the cake🍰: we will be applying SAP Principal Propagation under the hood in Azure API Management (APIM). This concept empowers all your client apps to primarily deal with business logic rather than SAP authentication specifics. Azure AD secures access to the APIs while honouring the SAP OAuth server as final validator.
Fig.1 API interface definition flow overview
Once the APIs are registered in APIM, we are ready to enrich them with sophisticated functionalities like request-throttling, user mapping (aka. SAP Principal Propagation via OAuth2SAMLBearerAssertion flow) and token caching.
|🛈 Note: Every OData service exposed via the SAP Gateway could potentially be added to APIM without additional involvement by the NetWeaver Administrators. However, for SAP Principal Propagation as described in this blog the services need to be activated for OAuth. Enablement can be done from transaction /IWFND/MAINT_SERVICE on the SAP Gateway.|
Exporting the API from APIM to Power Automate enables a low code environment to profit from this generalized and central setup. All your client apps may use the same API. Authorization is delegated to Azure AD.
Let’s look at the moving parts 🏊
See below the specifics for Power Platform but keep in mind it is not limited to that.
Fig.2 Data flow after API is introduced in Power Automate
The official docs for SAP APIs in Azure get you started fine, but there are some tweaks required to be plug & play for restrictive external environments. We supply switches to adhere to the OpenAPI policies of our consumer. Find the open-source web-based converter here and the associated GitHub repos here.
Fig.3 Screenshot of OData to OpenAPI converter
Paste your OData definition and check the “Optional Parameters” Section to maintain your service specific parameters.
If you don’t want to put your potentially sensitive connection information on the webapp despite being open-source and no data storage beyond processing, maintain manually afterwards.
Fig.4 Screenshot of conversion parameters
To support exportability and expose OData update capabilities (e.g., ETags) from Azure APIM to Power Automate we need to switch on post-processing features as shown above. For direct import into Power Automate (without Azure APIM in between) switch the swagger override too. In that case OAuth2 and Azure AD tenant id will come handy as well.
We will continue the narrative via APIM and therefore discard the swagger override and maintain OAuth2 manually.
Our target OData service lives on this endpoint:
https://<your domain or ip>:<ssl port>/sap/opu/odata/iwbep/gwsample_basic/
Fig.5 Screenshot of conversion result
Once you hit the convert button from the “OData Definition” section you get your conversion result. Oasis maintains different approaches for the different versions of OData. To support “conversion clarity” we display the version, that was anticipated based on the input schema.
So, let’s save the new OpenAPI spec for our OData service and upload into Azure APIM. Therefore, navigate to your APIM instance.
Fig.6 Screenshot of API create from OpenAPI
Fig.7 Screenshot of Import-Wizard
We recommend supplying the original SAP path as URL suffix to support BTP clients. Some apps anticipate the standard paths (e.g., the OData discovery service in SAP Business Application Studio). Those would break otherwise. We keep “test” as an example.
Verify the newly created API and adjust the required subscription setting. We will rely on AAD and SAP OAuth server instead😊
Fig.8 Screenshot of unchecked subscription requirement
Before we export the definition, we finish the API setup to enable SAP Principal Propagation, X-CSRF-Token handling, and JSON response formatting. We offer a pre-defined Azure APIM policy for that purpose here. In case you are looking for CSRF token handling only, have a look here.
Be aware that this configuration is independent of the “exporting” to Power Automate. The policies remain in Azure APIM and the custom connector simply “points” towards them. Imagine the APIM team overseeing SAP APIs while the client apps only get authorization to interact with them. Basically, full control and freedom for your developers of SAP Integration challenges.
Exporting to your client app with a couple of clicks 🖱️
Find the export function via the three dots and maintain your target environment details.
Fig.9 Screenshot of export process
Before we finish the OAuth settings on Power Automate (or any client app really), we need to create an Application Registration on Azure AD to handle the authentication flow for this new client.
Take note of the application ID from the Overview pane, create a secret (Manage -> Certificates & Secrets) and maintain the API permission exposed by your API Management middle tier as described on our prior blog and GitHub repos.
Fig.10 Screenshot of API permission for APIM middle tier
Use the noted info to fill the Security tab of your custom connector on Power Automate (navigate Data -> Custom Connectors). You can choose Azure AD or Generic OAuth2 as identity providers. I picked generic due to its greater familiarity with the SAP terms regarding OAuth2.
Fig.11 Screenshot of custom connector OAuth2 settings
Re-use the Token URL for the refresh token URL endpoint, put your APIM middle tier scope (if you follow our posts and guides it will be something like: api://your-app-id/user_impersonation) under Scope. Once you save, copy the Redirect URL field at the bottom to finish the setup on the app registration for this custom connector. That will likely be “https://global.consent.azure-apim.net/redirect”.
Fig.12 Screenshot of redirect URL setting after custom connector update
That leaves the Connection setting as final step before we can start testing. There are two options. Maintain the connection from the flow designer or on custom connector level. For the latter navigate to the Test pane on the setup screen and add a connection. The user needs to be allowed to call the front-end application. If you prefer the flow designer, the creation wizard will create the connection during the design process.
Ready to see some action? 🎬
Create a new flow and choose your new shiny custom connector as flow step. That brings up all the SAP API endpoints hosted by APIM 😊
Fig.13 list of all SAP OData operations exposed by imported API
We will choose “Get entity from ProductSet by key”, to prove principal propagation and data write back to the SAP backend. So, pick “Update Entity in ProductSet” next. Supply the product ID from your first GET operation alongside the ETag for the if-match header. OData relies on the ETag concept for update concurrency. Every update operation requires it and the converter presented in this blog post ensures it gets surfaced to the API user via the response header and __metadata property. I will retrieve it from the metadata using an expression like so:
Now, let’s raise the product price and enjoy the SAP data update from your client app, that doesn’t need to care about SAP Principal Propagation, CSRF-tokens, and backend server resource consumption anymore. All that gets taken care of by Azure APIM 😊
Fig.14 Raise price in SAP from client app
Hit the test button and marvel at the simplicity from the Developers point of view 🪄.
Fig.15 price change request result
Find more request details via the “Show raw inputs/outputs” button. It contains the http headers, metadata etc.
What about other popular software runtimes? 💕
Great, we can enable client applications via OpenAPI definitions in various flavours but what about SDKs for full-code developers? We are glad you are asking. The converter is currently being integrated with the AutoREST library to generate SDKs for your OData service out of the box. AutoREST covers Python, Java, NodeJS, PowerShell, Go, C# and TypeScript. Enhance Java & NodeJS with SAP Cloud Application Programming Model and SAP Cloud SDK libs in a second step.
You get the programming language dependent scaffolding as a package download, so you can hit the ground running. Not too bad, huh? 😉
Stay tuned for more updates regarding this topic.
Production Readiness 🏭
The UI-based flow introduced in this blog is nice for a small number of integration endeavours and to get started. But of course, for enterprise scale, we need to employ APIOps practices to be able to maintain thousands of APIs with different configurations and automatically govern them and their lifecycle in your API Management solution.
A first step could be adding the Azure function powering the UI and flow described in this post to your CD pipeline, so you can run it automatically on every new OData API that you add to your landscape. The Azure Function code is open-source and shared as part of the GitHub repos.
Further Reading 📰
- Microsoft Docs for SAP OData import into Azure APIM
- Principal Propagation policy
- CSRF-Token policy
- DotNET project implementing APIM policy and corresponding blog post
- Exposing your SAP APIs with SAP Graph
- Hybrid API Management for SAP
- Hands-On Lab: Combining the Microsoft-Graph and SAP-Graph in a Microsoft Teams and Azure Bot scenario
Final Words 🥇
Uhh, what a ride. We converted SAP OData APIs into OpenAPI definitions to make them compatible with other open standards widely used in the application development industries. This approach eases the race for rare ABAP developers and addresses SAP’s initiative to avoid extensions within the ABAP core.
As an example, to act upon the alternative API definition we implemented Power Automate. Fronting those APIs via an API Management solution such as Azure APIM brings the additional benefit that client applications and developers can be freed of the burden of SAP specific authentication mechanisms and profit from native security mechanisms on Azure.
SAP Admins get piece of mind due to service throttling capabilities and complete coverage of SAP Principal Propagation all governed in one single place. APIOps and SDK generation based upon the SAP OData services top off the approach.
As always feel free to ask lots of follow-up questions.
Will and Martin