Technical Articles
cf for your pocket
or more precisely: running your UI locally Cloud Foundry-style, connected to a “real” Backend.
During my talk about the concept of a digital marketplace for the dive industry on this year’s UI5con, I showed a setup that mimics the SAP Cloud Platform Cloud Foundry (SAP CP cf) for local development.
Context
When developing an application following the guidelines of the Cloud Application Programming Model (CAP), a so-called mta
file needs to be generated for deployment – either within the WebIDE or with the help of the CLI tool. The mta
file can then be deployed to SAP CP cf.
The engine behind running the application on Cloud Foundry is the @sap/approuter
.
It’s an npm
module that delivers the UI as a webserver (“static resources” in the above diagram) and proxies service-requests to either local or remote URLs via the Cloud Platform’s “destination” concept.
And it’s possible to re-use all of that for local development!
local setup
It’s essentially a 3-step process (see my corresponding github repo for complete example)
- install
@sap/approuter
locally# make sure you have the sap npm repo set up: # npm config set @sap:registry https://npm.sap.com npm install @sap/approuter
- utilize
@sap/approuter
‘s runtime// index.js // note that xs-app.json in your "regular" SAP HANA XS // config file that's also required for any SAP CP cf-style // CAP-like application const approuter = require('@sap/approuter'); const fs = require('fs'); const xsAppConfig = JSON.parse(fs.readFileSync('xs-app.json', 'utf8')); const ar = approuter(); ar.start({ xsappConfig: xsAppConfig });
- configure
destinations
at runtime// xs-app.json { "authenticationMethod": "none", "welcomeFile": "/index.html", "routes": [ { "source": "^/backend/(.*)$", "destination": "backend", "target": "$1" }, { "source": "^/(.*)", "localDir": "./webapp", "cacheControl": "no-cache, no-store, must-revalidate" } ] } // index.js process.env.destinations = '[' + '{"name": "backend","url": "https://services.odata.org/V4/(S(fdng4tbvlxgzpdtpfap2rqss))/TripPinServiceRW/"}' + ']';
The
approuter
interprets thenode
environment variabledestinations
– pass in an array of key-value pairs (name
,url
) and it will automagically proxy those requests for you! In the example above, every request to/backend
ist automatically proxied to the TripIt OData Service athttps://services.odata.org/...
Important: the
destination
name of the route inxs-app.json
and thename
value inprocess.env.destinations
must match!
Now, all that’s left is to fire up the engine:
node index.js
will present you http://localhost:5000 – including proxy access to the example OData Service via http://localhost:5000/backend
??
Hi Volker,
a great blog post! This is a really handy trick
I will remember.
Btw: It would be possible to get rid of the index.js file and to inject the environment variable via the start script:
I know this looks a little bit ugly because of the escaped quotation marks (and it’ll get more ugly, the more destinations you use).
A further improvement could be achieved by the usage of dotenv which automatically imports data into the env var.
Whereby the destination is stored in the ‘.env’ file
Hi Marius,
nice abstraction case 🙂
Best,
Volker
Hi Volker,
maybe you should update your blog with the information from:
https://cap.cloud.sap/docs/node.js/authentication#jwt
and:
https://github.com/gregorwolf/SAP-NPM-API-collection/tree/master/apis/approuter#configurations
to use the default-env.json to store the destination & XSUAA information.
Best regards
Gregor