In this last exercise, we will expose all our calculation views as individual entity sets of an OData service.
-
Right-click on the project name and select New -> NodeJS Module
-
Call the module
all_routes
and press Next -
You can give the module a description if you wish, but the important option here is to switch on the "Enable XSJS Support" flag.
Press "Finish"
-
Open the file
all_routes/server.js
and change the value of theredirectUrl
property on line 10 to the following:"/xsodata/AllRoutes.xsodata?$format=json"
The entire
options
object should now look like this:var options = { anonymous : true, // remove to authenticate calls redirectUrl : "/xsodata/AllRoutes.xsodata?$format=json" };
Notice here that we have told the
xsjs
server to redirect incoming requests to an.xsodata
file calledAllRoutes
.We now need to create this file.
-
Right-click on the
all_routes/lib
folder and create a new folder calledxsodata
-
Right-click on the new
all_routes/lib/xsodata
folder and create a new file calledAllRoutes.xsodata
-
The objective here is to expose each calculation view as a separate entity set within an OData service. Enter the following CDS definition into the file
AllRoutes.xsodata
:service { "route0stop" as "DirectFlights" keys("ID") parameters via entity; "route1stop" as "OneStop" keys("routeText", "airlineText") parameters via entity; }
This declaration does the following:
-
The OData service name is derived from the filename. In this case
AllRoutes
. -
Each calculation view is exposed as an entity set within this service using this syntax:
<calculation view name> as <entity set name>
-
The
keys("ID")
part is needed because all OData entities require a key field (even if that key serves no purpose). This statement causes a dummy key field calledID
to be generated -
parameters via entity
causes the input parameters for each calculation view (airportFrom
andairportTo
) to be made visible through a corresponding entity set ending with the wordParameters
-
-
Modify the
mta.yaml
to create a dependency from theall_routes
NodeJS module to thespacetravel-db
andspacetravel-hdi-container
modules.-
Open the
mta.yaml
file -
Select the MTA Editor from the tab at the bottom of the editor screen
-
Select the
all_routes
module -
Expand the "Requires" section and using the
+
button, add two dependencies tospacetravel-db
andspacetravel-hdi-container
. These names will be available from the drop down list.Your screen will now look like this
-
-
Right-click on the
all_routes
NodeJS app name and select Run -> Run as NodeJS ApplicationWhen you select this option for the first time, it will take some time to work because an
npm install
is being run behind the scenes to generate a new NodeJS application. This app is then deployed to the SAP Cloud Platform. Running this option a second time is always much quicker (unless you change something like thepackage.json
file) -
Once the build and deploy has finished, at the bottom of the SAP Web IDE screen, you will see a message saying "Application is running" and above, you will see the URL to the running app.
-
Click on this URL and you will see running app in a new browser tab
-
Due to the fact that in
server.js
we redirected the request to/xsodata/AllRoutes.xsodata?$format=json
, we immediately see following output:{ "d": { "EntitySets": [ "DirectFlights", "OneStop", "DirectFlightsParameters", "OneStopParameters" ] } }
Notice that each of our entity sets has a corresponding
Parameters
entity set. So in order to read some data from a calculation view, we must do so using aParameters
entity set. -
Here we will search for direct flights from London Heathrow to New York John F. Kennedy. To invoke this search, change the URL to the following:
xsodata/AllRoutes.xsodata/DirectFlightsParameters(airportFrom='LHR',airportTo='JFK')/Results
The general pattern of the URL is shown in this table
URL Segment Meaning xsodata/AllRoutes.xsodata
The OData service name DirectFlightsParameters
The entity set name (airportFrom='LHR',airportTo='JFK')
The search predicate /Results
The entity set name containing the search results -
Invoking the above search will generate search results similar to the following
{ "d": { "results": [ { "__metadata": { "uri": "https://wham6fjzs2eaoz5tt-hana-all-routes.cfapps.eu10.hana.ondemand.com/xsodata/AllRoutes.xsodata/DirectFlights('LHRJFKAA')", "type": "default.DirectFlightsType" }, "ID": "LHRJFKAA", "DISTANCE": 5541, "STARTINGAIRPORT_IATA3": "LHR", "DESTINATIONAIRPORT_IATA3": "JFK", "AIRLINE_IATA2": "AA", "EQUIPMENT_AIRCRAFT1_EQUIPMENTCODE": "77W", "EQUIPMENT_AIRCRAFT2_EQUIPMENTCODE": "777", "EQUIPMENT_AIRCRAFT3_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT4_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT5_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT6_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT7_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT8_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT9_EQUIPMENTCODE": null, "routeText": "LHR->JFK" }, { "__metadata": { "uri": "https://wham6fjzs2eaoz5tt-hana-all-routes.cfapps.eu10.hana.ondemand.com/xsodata/ AllRoutes.xsodata/DirectFlights('LHRJFKAF')", "type": "default.DirectFlightsType" }, "ID": "LHRJFKAF", "DISTANCE": 5541, "STARTINGAIRPORT_IATA3": "LHR", "DESTINATIONAIRPORT_IATA3": "JFK", "AIRLINE_IATA2": "AF", "EQUIPMENT_AIRCRAFT1_EQUIPMENTCODE": "76W", "EQUIPMENT_AIRCRAFT2_EQUIPMENTCODE": "764", "EQUIPMENT_AIRCRAFT3_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT4_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT5_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT6_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT7_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT8_EQUIPMENTCODE": null, "EQUIPMENT_AIRCRAFT9_EQUIPMENTCODE": null, "routeText": "LHR->JFK" } <snip> ] } }