3. Delegating Requests - SAP-samples/teched2022-AD265 GitHub Wiki
In this exercise, you will make a new Customers
entity available, so that the user can pick customer data in a value list.
Create a new file srv/mashup.cds
and add this snippet, so that Customers
appears in the API of the IncidentsService
:
using { acme.incmgt, IncidentsService } from './incidents-service';
using { s4 } from './external';
extend service IncidentsService with {
entity Customers as projection on s4.simple.Customers;
}
Also in the same file, add an association from Incidents
to Customers
, to allow queries on which incident refers to which customer (like /Incidents('...')/customer
):
extend incmgt.Incidents with {
customer : Association to s4.simple.Customers;
}
To make the value help for Customers
work, we need to redirect the request to the remote system (or our mock).
Otherwise, the framework would read it from a local DB table, which does not exist.
So, in file srv/incidents-service.js
, add this snippet inside the existing function:
const cds = require('@sap/cds');
const S4bupa = await cds.connect.to('API_BUSINESS_PARTNER')
// Delegate Value Help reads for Customers to S4 backend
this.on('READ', 'Customers', (req) => {
console.log('>> delegating to S4 service...')
return S4bupa.run(req.query)
})
As a ready-to-use remote service, we use the sandbox system of SAP API Business Hub.
To use your own SAP S/4HANA Cloud system, see this tutorial. You don't need it for this tutorial though.
-
Create a new file
.env
in theincidents
folder and add environment variables that hold the URL of the sandbox as well as a personal API Key:DEBUG=remote cds.requires.API_BUSINESS_PARTNER.[sandbox].credentials.url=https://sandbox.api.sap.com/s4hanacloud/sap/opu/odata/sap/API_BUSINESS_PARTNER/ cds.requires.API_BUSINESS_PARTNER.[sandbox].credentials.headers.APIKey=<Copied API Key>
Note the
[sandbox]
segment which denotes a configuration profile namedsandbox
. The name has no special meaning. You will see below how to use it. -
Get an API key:
-
Go back to the Business Partner (A2X) API page.
-
Choose Show API Key on the right.
-
Choose Copy Key and Close.
-
-
Add the key to the
.env
fileBy putting the key in a separate file, you can exclude it from the Git repository (see the
.gitignore
file).Also note how the
cds.requires.API_BUSINESS_PARTNER
structure in the.env file
matches to thepackage.json
configuration.
To learn about more configuration options for CAP Node.js applications, see the documentation.
Now kill the server with Ctrl+C and run again with the profile activated:
cds watch --profile sandbox
In the server log, you can see that the configuration is effective:
...
[cds] - connect to API_BUSINESS_PARTNER > odata-v2 {
url: 'https://sandbox.api.sap.com/s4hanacloud/sap/opu/odata/sap/API_BUSINESS_PARTNER/',
headers: { APIKey: '...' }
}
...
On the application's index page, the mocked service is gone, because it is no longer served in the application. Instead, it is assumed to be running in a remote system. Through the configuration above, the system knows how to connect to it.
Open /incidents/Customers
to see the data coming from the remote system.
If you get a
401
error instead, check your API key in the.env
file. After a change in the configuration, kill the server with Ctrl+C and start it again.
You can also see something like this in the log (due to the DEBUG=remote
variable from the .env
file above):
[remote] - GET https://.../API_BUSINESS_PARTNER/A_BusinessPartner
?$select=BusinessPartner,BusinessPartnerFullName&$inlinecount=allpages&$top=74&$orderby=BusinessPartner%20asc
...
This is the remote request sent by the framework when S4bupa.run(req.query)
is executed. The req.query
object is transparently translated to an OData query $select=BusinessPartner,BusinessPartnerFullName&$top=...&$orderby=...
. The entire HTTP request (completed by the sandbox URL configuration) is then sent to the remote system with the help of SAP Cloud SDK.
Note how simple the execution of remote queries is. No manual OData query construction needed, no HTTP client configuration like authentication, no response parsing, error handling, issues like hard-wired host names etc.
See the documentation on CQN for more on such queries in general. The service consumption guide details out how they are translated to remote requests.
The UI needs some more annotations to show the changed data.
-
Put basic annotations that refer to
Customers
itself insrv/external/index.cds
, next to theCustomers
definition:annotate Customers with @UI.Identification : [{ Value:name }]; annotate Customers with @cds.odata.valuelist; annotate Customers with { ID @title : 'Customer ID'; name @title : 'Customer Name'; }
-
Annotations that refer to
Incidents
or its association toCustomers
should go to filesrv/mashup.cds
. Add this snippet there:// import annotations from rest of the application using from '../app/fiori'; annotate IncidentsService.Incidents with @( UI: { // insert table column LineItem : [ ...up to { Value: title }, { Value: customer.name, Label: 'Customer' }, ... ], // insert customer to field group FieldGroup #GeneralInformation : { Data: [ { Value: customer_ID, Label: 'Customer'}, ... ] }, } ); // for an incident's customer, show both name and ID annotate IncidentsService.Incidents:customer with @Common: { Text: customer.name, TextArrangement: #TextFirst };
Don't change the ellipsis
...
in thecds
code above. It's a special syntax for refering to the 'remaining values' of array-valued annotations. The advantage of this syntax is that you do not have to repeat the other table columns. See the documentation for more.
Now Open Fiori preview for the Incidents
entity.
Create a new incident and select a customer using the value help. When pressing Save, watch the console output of the application and see the >> delegating to S4 service...
message.
When you integrate data from SAP S/4HANA, CAP applications use the SAP Cloud SDK underneath. It is a set of libraries that reduce the effort of building applications on the SAP Business Technology Platform (SAP BTP).
SAP Cloud SDK abstracts authentication flows and communication with SAP BTPs connectivity, destination, and XSUAA services. It doesn't matter whether you want to connect against Cloud or On-premise systems.
For applications not using CAP, SAP Cloud SDK helps you build your own typed clients for any OData or REST service to easily connect to your and SAP's systems.
In the next exercise, you will use data replication to display local and remote data in a performant way.