Preface – This post is part of the SAP Multi-Target Application (MTA) series.
Table of Contents
Introduction
To ease the problem of developers, SAP has provided MTA services where we directly call any API under node.js file and this node.js is then utilized by UI5 App as an API. Hence, we neither need any destination setup nor crucial APIs are getting exposed. Thus SAP Node.js Development in MTA is a very important concept.
SAP Node.js App Structure
As it can be seen below, under our App folder xs.js we have many files and folders. In this section we will be mainly focusing upon package.json, config.json and server.js.
PACKAGE.JSON
This is a file, where we define all the packages/libraries that will be used by our Node.js App. You can find some of them will be already defined/provided by SAP. You need to just add the one that you will be using with its version, as shown below:
{ "dependencies": { "@sap/xsenv": "^1.2.9", "@sap/xsjs": "^4.0.1", "express": "~4.15", "passport": "~0.3.2", "@sap/xssec": "^2.1.11", "node-sap-logging": "0.3.0", "sap-hdbext-promisfied": "1.0.0" }, "description": "my description", "devDependencies": { "@sap/xsjs-test": "^3.0.2" }, "files": [], "main": "server.js", "name": "xs.js", "scripts": { "start": "node server.js", "test": "node testrun.js" }, "engines": { "node": "8.x" }, "version": "1.0.0" }
CONFIG.JSON
This is a local JSON file created to store all the calling APIs details. These details are the APIs provided by Blockchain Application Enablement Service.
{
“tokenUrl”: “YOUR_TOKEN_URL”,
“blockServUrl”: “YOUR_BLOCKCHAIN_URL”,
“authorization”: “Basic YOUR_UNIQUE_API_KEY”
}
SERVER.JS
Under this file we will be writing all the Node.js codes, as shown below [just an example]:
/*eslint no-console: 0, no-unused-vars: 0*/ "use strict"; var https = require("https"); var request = require("@sap/xsjs/node_modules/request"); var xsjs = require("@sap/xsjs"); var xsenv = require("@sap/xsenv"); var port = process.env.PORT || 3000; var express = require("express"); var globalBody; var app = express(); var configData = require("./config.json"); var options, data, token; // setting Response app.set('json spaces', 1400); app.use(function (req, res, next) { res.setHeader("Access-Control-Allow-Origin", "*"); res.setHeader("Access-Control-Allow-Credentials", "true"); res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"); res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, access-control-allow-origin, cache-control" ); next(); }); // configure token var headeroptions = { method: 'GET', url: configData.tokenUrl, qs: { grant_type: 'client_credentials' }, headers: { 'cache-control': 'no-cache', Authorization: configData.authorization } }; // get proof history request(headeroptions, function (error, response, body) { if (error) throw new Error(error); data = JSON.parse(body); token = data.access_token; var proofoptions = { method: 'GET', url: configData.blockServUrl + '/logon', headers: { 'cache-control': 'no-cache', 'Content-Type': 'application/json', Accept: 'application/json', Authorization: 'Bearer ' + token } }; request(proofoptions, function (error, response, body) { if (error) throw new Error(error); console.log(body); globalBody = body; }); }); // update proof history app.get('/UPDATE_OBJECT_HISTORY', function (req, res, next) { var uname = req.query.USERNAME; var pass = req.query.PASSWORD; var dats = req.query.TIMESTAMP; // Get Token var tokenoptions = { method: 'GET', url: configData.tokenUrl, qs: { grant_type: 'client_credentials' }, headers: { 'cache-control': 'no-cache', Authorization: configData.authorization } }; request(tokenoptions, function (error, response, body) { if (error) throw new Error(error); data = JSON.parse(body); token = data.access_token; var dataoptions = { method: 'PATCH', url: configData.blockServUrl + '/logon', headers: { 'cache-control': 'no-cache', 'Content-Type': 'application/json', Accept: 'application/json', Authorization: 'Bearer ' + token }, body: { USERNAME: uname, PASSWORD: pass, TIMESTAMP: dats }, json: true }; request(dataoptions, function (error, response, body) { if (error) throw new Error(error); res.json(globalBody); }); }); }); // send proof history as response app.get('/GET_PROOF_HISTORY', function (req, res, next) { res.json(globalBody); }); options = { anonymous: true, // remove to authenticate calls auditLog: { logToConsole: true }, // change to auditlog service for productive scenarios }; // configure token HANA try { options = Object.assign(options, xsenv.getServices({ hana: { tag: "hana" } })); } catch (err) { console.log("[WARN]", err.message); } // configure UAA try { options = Object.assign(options, xsenv.getServices({ uaa: { tag: "xsuaa" } }));
Once, we are done with the Node.js development we need to run our file, then only we will be able to access it. For that we will run it as shown below:
Once, we will run it, we will get an API in node.js console and the same will be utilized in the UI5 App.
0 Comments