Business Example
We will now look at how to create a CAP-based service.
Exercise Options
You can perform this exercise in two ways:
- Live Environment - using the following instructions provided, you can perform the steps in the SAP BTP Free Tier account
- Platform Simulation – follow the step-by-step instructions within the simulation by choosing the Start Exercise button
Prerequisites
Before proceeding with the exercise make sure you:
- Successfully created a SAP BTP Free Tier account.
- Created and opened your Dev Space for Full Stack Cloud Applications in the SAP Business Application Studio.
In case you haven't created yet a Dev Space, follow the simulation below to see the steps involved.
Steps
Create and initialize the project.
In the Business Application Studio, choose Terminal → New Terminal.
A new terminal opens in the lower-right part of the Business Application Studio screen.Enter the following commands to clone the starter template from GitHub and press Enter after each command.
Code snippetExpandmkdir ~/projects/risk-management cd ~/projects/risk-management/ git clone https://github.com/SAP-samples/extension-suite-learning-journey ./
The output in the terminal should then look similar to the following (the output can differ).
So, the template from GitHub has been cloned successfully. Next, open it in the project explorer.
Note
In case of issues: The template you have cloned also contains aTROUBLESHOOTING.md
file. In case of any issues during the exercises, refer to this document first for known issues. In addition, ensure to periodically fetch the latest troubleshooting guide from GitHub.In case you're stuck or want to specifically start with a later exercise, you also have the possibility to switch to the solution branch of the respective exercise. Every exercise of this course comes with its solution branch. You have also cloned them through the command above.
On the Welcome page, choose Files & Folders.
Now select the risk-management folder in the projects folder and click on Open. The SAP Business Application Studio will now reload to open the folder.
On the left side you will now see the content of the risk-management folder.
In Business Application Studio, choose Terminal → New Terminal from its menu.
A new terminal opens in the lower-right part of the Business Application Studio screen.
In the terminal, run the command
This might take a while. It installs all the dependencies of your project, which are listed in the
package.json
andpackage-lock.json
file, into a new folder callednode_modules
within theroot
of your project. If you encounter messages aboutDeprecated
dependencies ignore them for now, as long as there are no errors in the log.In the terminal, start a CAP server by typing:
The CAP server serves all the CAP sources from your project. It also "watches" all the files in your projects and conveniently restarts the server whenever you save a file. Changes you've made will immediately be served without you having to do anything.
The terminal now looks like this:
cds watch
tells you that there’s no model yet that it can serve. You add one in the next steps.Note
In general, you can keep
cds watch
running in a terminal for the whole exercise. There is no need to restart it or try to add a second instance of it (in fact, if you do this, you get an error, described here). In the follow-up steps, you will open a new browser tab to see the results ofcds watch
. You can just keep this open and refresh it each time there is a change.cds watch
notices any file change and makes sure you get the new results after a refresh in the browser.
Add a data model to the project.
Create a data model using the Core Data Services (CDS) format from CAP.
In the project, go to folder
db
, representing the data model on the database. In the context menu, select New File.Enter schema.cds as a name.
Click on the new file in the explorer.
An editor opens.
Enter the following lines into the editor.
Code snippetExpandnamespace riskmanagement; using { managed, cuid, User, sap.common.CodeList } from '@sap/cds/common'; entity Risks : cuid, managed { title : String(100); owner : String; prio : Association to Priority; descr : String; miti : Association to Mitigations; impact : Integer; // bp : Association to BusinessPartners; virtual criticality : Integer; virtual PrioCriticality : Integer; } entity Mitigations : cuid, managed { descr : String; owner : String; timeline : String; risks : Association to many Risks on risks.miti = $self; } entity Priority : CodeList { key code : String enum { high = 'H'; medium = 'M'; low = 'L'; }; }
Save the file.
You are using the namespace1
riskmanagement
. A namespace is optional. It is helpful to use short unique names without bloating the code with fully qualified names. Essentially, namespaces are just prefixes that are applied to all relevant names in a file automatically.The code creates 2 entities in the namespace
riskmanagement
,Risks
, andMitigations
. Each of them has a key calledID
and several other properties. ARisk
has a mitigation and therefore, the propertymiti
has an association to exactly oneMitigation
. AMitigation
in turn can be used for manyRisks
, so it has a "to many" association. The key is automatically filled by CAP, which is exposed to the user of the service with the annotation@(Core.Computed : true)
.At this point, you can ignore the commented property
bp
(as well as the other commented lines further down in the file and in subsequent files and steps). You will use the commented lines at a later stage of the project.The screen now looks like this:
Take note of how
cds watch
reacts to dropping the file. It now tells you that it has a model but there are no service definitions yet and thus it still can’t serve anything. So, in the next step you will add a service definition.
Add a service definition to the project.
In this part, you will create a new service with two entities. Both are projections of the data models that you created in the previous step. A service provides an interface to the application. It enables other applications and users outside of the application to interact with it. In this case, the service lets us interact with the
Risks
andMitigations
entities, thus the data within the application. For this, create a file calledrisk-service.cds
in thesrv
folder with the following content:Code snippetExpandusing {riskmanagement as rm} from '../db/schema'; @path: 'service/risk' service RiskService { entity Risks as projection on rm.Risks; annotate Risks with @odata.draft.enabled; entity Mitigations as projection on rm.Mitigations; annotate Mitigations with @odata.draft.enabled; // BusinessPartner will be used later //@readonly entity BusinessPartners as projection on rm.BusinessPartners; }
Provide mock data for the service.
In CAP, there is a way to provide mock data for the created entities. The data is stored in a local database called SQLite that CAP invokes behind the scenes. CAP makes it easy to add such test data to a service. All it needs is a Comma Separated Values (CSV) file that contains the entities' elements as column headers. Note that the separation of values in this case has to be done using semicolons (
;
) by convention.In the project, go to folder db/ and then into the data/ folder.
There is already one file called
riskmanagement-Risks.csv
:In a table format, the header and one line of the file content look like the following:Code snippetExpandID;createdAt;createdBy;title;owner;prio_code;descr;miti_ID;impact; 20466922-7d57-4e76-b14c-e53fd97dcb11;2019-10-24;SYSTEM;CFR non-compliance;Fred Fish;H;Recent restructuring might violate CFR code 71;20466921-7d57-4e76-b14c-e53fd97dcb11;10000; 20466922-7d57-4e76-b14c-e53fd97dcb12;2019-10-24;SYSTEM;SLA violation with possible termination cause;George Gung;M;Repeated SAL violation on service delivery for two successive quarters;20466921-7d57-4e76-b14c-e53fd97dcb12;90000; 20466922-7d57-4e76-b14c-e53fd97dcb13;2019-10-24;SYSTEM;Shipment violating export control;Herbert Hunter;L;Violation of export and trade control with unauthorized downloads;20466921-7d57-4e76-b14c-e53fd97dcb13;200000;
ID createdAt createdBy title owner prio descr miti_id impact 20466922-7d57-4e76-b14c-e53fd97dcb11 2019-10-24 SYSTEM CFR non-compliance Fred Fish 3 Recent restructuring might violate CFR code 71 20466921-7d57-4e76-b14c-e53fd97dcb11 10000 There is also another file for the Mitigations and Priority entity called.
Click on the file in the explorer:
The files have the name of the namespace of the entities in the data model (for example, riskmanagement), followed by a '-' and the name of the entity (for example, Risks). When adhering to this naming convention, CAP recognizes the file as data for the data model and automatically adds it to the built-in SQLite database. Looking at the contents of the file riskmanagement-Risks.csv, the first line contains all the properties from your Risks entity. While the other ones are straightforward, consider the miti_id property. In your entity, you only have a miti property, so where does this come from? miti is an association to Mitigations, as Mitigations could have several key properties, the association on the database needs to point to all of these. Therefore, CAP creates a property
<AssociationProperty>_<AssociatedEntityKey>
for each key.As always, cds watch has noticed that there are files containing the mock data.
Other fields like HasDraftEntity were added because you added the @odata.draft.enabled annotation in the service definition (risk-service.cds).
You’ve now got a full-blown OData service, which complies to the OData standard and supports the respective queries without having to code anything but the data model and exposing the service itself.
Note
The service is completely exposed without any authentication or authorization check. You will extend the service later with such checks.
Platform Simulation
Choose the Start button below to open a simulation of the platform. Then follow the step-by-step instructions to create a CAP-based Service.
ExerciseStart Exercise
Result
You have added a data model, data, and a service definition to your project. In the next unit, you will create a UI for your application.