Use the SAP Cloud SDK in the Browser
The SAP Cloud SDK for JavaScript can be used both as a backend and frontend library when used in a browser.
Because of the specifics of a browser environment, some features might be unavailable.
To help you get up and running faster in a browser, we'll outline the main steps and caveats of using SAP Cloud SDK on the frontend.
We will use Angular
to illustrate the usage.
Prerequisite
You have a frontend application set up.
For example an Angular application via ng new myProject
.
Include the SAP Cloud SDK
For most examples, we will use the business partner API.
Add the package @sap/cloud-sdk-vdm-business-partner-service
to your package.json and introduce some calls via:
//In the .html part of the component
<button (click)="callApi()">Click me!</button>
//In the .ts part of the component
import { BusinessPartner } from '@sap/cloud-sdk-vdm-business-partner-service'
async function callApi(){
const result = await BusinessPartner.requestBuilder().getAll().execute(myDest)
console.log(result)
}
For the destination lookup, the SAP Cloud SDK relies on Node.js
functionality like process.env
for example.
However, the request building, execution, and result parsing do not require any Node.js
modules and can be used on the frontend.
Hence, you have to create the destination variable myDest
manually.
When you run npm run build
your project should compile.
Currently, we are facing compilation errors of the kind Module not found: Error: Can't resolve 'https' in ...'
Please check out the workaround for these kinds of errors.
Run Locally
As discussed above the myDest
can not be fetched via the destination service.
When you run locally you can simply provide it.
import { Destination } from '@sap-cloud-sdk/core';
const myDest: Destination = {
url: 'https://my123456.s4hana.ondemand.com',
username: 'myUser',
password: 'myPassowrd'
};
When you execute npm run serve
your project is compiled and hosted on a local server.
When you trigger a request from a browser to the remote system all modern browsers will block this to ensure same origin policy.
One simple way to overcome this issue locally is to disable the web security of your browser temporarily (e.g. --disable-web-security for Chrome).
Alternatively, you can also create a second localhost proxy server that adds the access-allow-origin-header
to the request.
Run on SAP BTP, Cloud Foundry Environment
For productive usage, the methods mentioned above for running locally are of course not needed.
You configure the xs-app.json
of the used app-router with an entry like this:
{
"source": "/REMOTE-SYSTEM-IDENTIFIER/(.*)",
"target": "/$1",
"destination": "DESTINATION-NAME-ON-CF"
}
and then in your application define the destination as:
import { Destination } from '@sap-cloud-sdk/core';
const myDest: Destination = {
url: '/REMOTE-SYSTEM-IDENTIFIER'
};
The created request to /REMOTE-SYSTEM-IDENTIFIER/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner
will be matched by the app-router and the destination with the given URL and credentials is used.
This approach does not support principal propagation to On-premise systems. For this, you need a JWT and need to include the proper header fields defining the user. See the documentation on On-premise systems for details.
With webpack it is possible to load resources for local or productive usage. Using such a switch you can adjust the value of the destination for the two cases.
Workaround
Currently, we are facing the issue, that during the compilation from TS to JS the Node.js
parts cause problems even if they are not used.
We hope to resolve these issues in the future but for now, here is a workaround:
- Include
@angular-builders/custom-webpack
in thedevDependencies
- Create a custom webpack configuration named
node-webpack.config.js
and list the following node modules:
module.exports = {
node: {
crypto: true,
stream: true,
zlib: true,
path: true,
os: true,
http: true,
https: true
}
};
- In the
angular.json
adjust thebuild
target to use the custom builder:
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./node-webpack.config.js"
}
...
- In the
angular.json
adjust theserve
target to use the custom builder as well:
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
- In the
package.json
exclude the node modules, that do not exist in the browser:
"browser": {
"fs": false,
"net": false,
"tls": false
}
Now the project should build and run locally.