This blog is part of a
series of tutorials explaining the usage of
SAP Cloud Platform Backend service in detail.
This blog is like an appendix:
We learned how to
call API from
REST client tool (e.g. Postman)
It is complicated, due to OAuth flow
So we learned a lot if interesting things around
OAuth:
What is
OAuth? And "
Authorization Code" ?
How to call my API from
node.js application?
And
more...
In all those great blogs we learned how to do the manual steps to overcome the OAuth protection
That was good learning – and we got used to it and it is OK
Now I’d like to propose an alternative: use
App Router
Deploy Application Router which routes to Backend service API
It is easy, just requires 3 little files
Advantage: App Router handles the OAuth flow for us (we need only Basic Authentication)
Disadvantage: Some effort to configure and deploy App Router (it is easy)
To learn about App Router you can follow my little series:
part 1 and
part 2 and
part 3
In this blog we're just doing the required steps:
Create App Router, redirecting to Backend service, facilitating calls from REST client
Prerequisites
Some APIs created in
SAP Cloud Platform Backend service and you user has role to access them
You might need node.js installed on your machine, including configured SAP registry (see
here)
Preparation
We’re going to create an application and deploy it to Cloud Foundry
This application wraps the App Router
It needs to be bound to an instance of XSUAA
That instance needs to contain the scope required by Backend service
To create such instance, see
here
Note:
For the present tutorial, we don’t need to create Service Key
In our example, we use the following name for the XSUAA service instance:
"XsuaaForAppRouterWithBs"
Create App Router Configuration App
Create application structure
On your local file system, create files and folders like shown below
- C:\dev\app
- manifest.yml
- C:\dev\app\approuter
- package.json
- xs-app.json
Configuration
manifest.yml
---
applications:
- name: ApprouterToBackendservice
host: tobs
path: approuter
memory: 128M
services:
- XsuaaForAppRouterWithBs
env:
destinations: >
[
{
"name": "backendservice_v2",
"url": "https://backend-service-api.cfapps.eu10.hana.ondemand.com/odatav2/DEFAULT/",
"forwardAuthToken": true
},
{
"name": "backendservice_v4",
"url": "https://backend-service-api.cfapps.eu10.hana.ondemand.com/odatav4/DEFAULT/",
"forwardAuthToken": true
}
]
Explanation:
We create a destination pointing to the root URL of an OData v2 service in Backend service
A second destination is meant for v4 services
In both cases, App Router does the OAuth flow and forward the access token to Backend service
Furthermore,
we define a binding to an existing XSUAA instance called "XsuaaForAppRouterWithBs"
If you’re using an XSUAA instance with different name, you need to adapt the name
We define a short host: tobs, because our app is only used to redirect to Backend service
If you get an error during deployment, make sure to change the host to some unique name
xs-app.json
{
"authenticationMethod": "route",
"routes": [
{
"authenticationType": "basic",
"csrfProtection": false,
"source": "^/bsv2/(.*)$",
"target": "$1",
"destination": "backendservice_v2"
},
{
"authenticationType": "basic",
"csrfProtection": false,
"source": "^/bsv4/(.*)$",
"target": "$1",
"destination": "backendservice_v4"
}
]
}
Explanation:
We define a route which points to the v2 root URL. To access this, route, we define a short URI-segment
bsv2 (points to Backend service, OData V2 services)
That entry point requires "only" "Basic Authentication"
Furthermore, the
x-csrf-token is not required (usually it is)
Similar configuration for OData V4 services
package.json
{
"name": "myapprouter",
"scripts": {
"start": "node node_modules/@sap/approuter/approuter.js"
},
"dependencies": {
"@sap/approuter": "^6.0.1"
}
}
Explanation:
Our app is a node.js app.
It is described by the
package.json file
In the
package.json file we declare a dependency to the existing default App Router module.
We declare: when our app is started, the javascript file to be executed is the
approuter.js, to be found in the existing approuter module
Means, our app does nothing than start the existing approuter, with our configuration
Note:
The version will probably change in future, so make sure to update it, if deployment fails
To update, run
npm install --save
Download App Router
Actually, downloading the App Router is not necessary.
The approuter is a node module which will be installed via
npm in the cloud environment.
As such, we can just deploy the app, as long as it contains the package.json file which tells how to install and run the approuter.
If it works, you don't need to install
node.js on your local machine
If you face dependency errors during deployment, then you need to download/install the approuter module via
npm into the application folder, on your local machine.
Only in that case, you need to install node.js on your local machine)
To download approuter, go to command shell, navigate to folder
c:\dev\app\approuter
There, execute the following command:
npm install --save
Deploy the app
Deploy the app to SAP Cloud Platform Cloud Foundry environment, like you’re used to (i.e.
command line or
cockpit)
Use it
After successful deployment, you have to find the host URL of your app, it is either on the command prompt, or in the app-overview in the cloud cockpit
In my example it is
tobs.cfapps.eu10.hana.ondemand.com
In order to route to our Backend service API, we have to append one of the defined routes (
bsv2), followed by the name of our API, as defined in Backend service (in my example
PRODUCTSERVICE)
In case of v4 service, we need to add the version parameter(
;v=1)
Example URLs:
https://tobs.cfapps.eu10.hana.ondemand.com/bsv2/PRODUCTSERVICE;v=1/
https://tobs.cfapps.eu10.hana.ondemand.com/bsv2/PRODUCTSERVICE;v=1/Products
Other service:
https://tobs.cfapps.eu10.hana.ondemand.com/bsv2/CUSTOMERSERVICE;v=1/
For odata v4, just change the route, e.g.:
https://tobs.cfapps.eu10.hana.ondemand.com/bsv4/PRODUCTSERVICE;v=1/Products
etc
Note:
If you switch from V2 service
https://tobs.cfapps.eu10.hana.ondemand.com/bsv2/PRODUCTSERVICE/
to v4
https://tobs.cfapps.eu10.hana.ondemand.com/bsv4/PRODUCTSERVICE/
you’ll get an error: Invalid URL
The reason is that the version param is required
https://tobs.cfapps.eu10.hana.ondemand.com/bsv4/PRODUCTSERVICE;v=1/
You can execute
POST, PATCH, DELETE etc like usual
Even x-csrf-token is not required (at least App Router doesn’t require it and Backend service - currently - either)
Troubleshooting
What to do if you happily deploy everything and try testing and get..... Forbidden ???
See
this blog for a Troubleshooting guide
Summary
We want to call our Backend service API from local REST client tool (e.g. Postman)
Instead of fetching OAuth access token, etc, we can do a different approach:
We can app an intermediate App Router in the cloud
That is an app which we have to deploy
That app contains a dependency to the actual App Router which is an existing node.js module
In the app, we configure the App Router such that it redirects to Backend Service
We configure that we can authenticate to our app with "Basic Authentication"
App Router fetches an OAuth access token and forwards it to Backend service
This makes life easier, because now, all APIs can be accessed from REST client without the tedious token-handling
Appendix: XSUAA creation command
If you're using command line, you'll find this copy&paste-ready command helpful.
It creates an instance of XSUAA service, with instance name "XsuaaForAppRouterWithBs"
cf create-service xsuaa application XsuaaForAppRouterWithBs -c "{\"xsappname\":\"XsuaaForAppRouterWithBs\",\"tenant-mode\":\"dedicated\",\"foreign-scope-references\":[\"$XSAPPNAME(application,4bf2d51c-1973-470e-a2bd-9053b761c69c,Backend-service).AllAccess\"]}"