Creating a CAP-Based Service

Objectives
After completing this lesson, you will be able to:

After completing this lesson, you will be able to:

  • Create a CAP-based service

Create a CAP-Based Service

Usage Scenario

You will create a new SAP Cloud Application Programming Model (CAP) project. This project provides the basis for your risk-management extension that comprises:

  • A database that stores application data.
  • A service that exposes the application data from the database via application programming interfaces (APIs).
  • A user interface that consumes the application data from the service and presents it to the end users.

In this lesson you will create:

  • A data model
  • A service definition

The data model defines what kind of data your application contains, how it is structured, and how it will be stored in the database.

The service definition defines which part of your data should be exposed as a service via APIs.

Exercise Options

You can perform this exercise in two ways:

  1. Live Environment - using the instructions provided below, you can perform the steps in the SAP BTP Free Tier account
  2. Platform Simulation – follow the step-by-step instructions within the simulation
Note
We are strongly recommending first performing the steps in the live environment.

Live Environment

In this exercise, you will perform the following steps:

  1. Create an SAP CAP project from our provided template on GitHub.
  2. Describe the role of a data model.
  3. Describe the purpose of a service definition.
  4. Add a data model to a project.
  5. Create a service definition.
  6. Add an OData service definition to a project.
  7. Provide Mock data in a CSV file for the project.

Prerequisites

Before proceeding with the exercise make sure you:

  1. successfully created a SAP BTP Free Tier account and a dev space.
  2. added and opened your Dev Space for Business Applications in SAP Business Application Studio.

In case you haven't created yet a Dev Space, follow the simulation below to see the steps involved.

Steps

  1. Create and Initialize the Project.

    1. In the Business Application Studio, click on TerminalNew Terminal.

      A new terminal opens in the lower right part of the Business Application Studio screen.

    2. Enter the following commands to clone the starter template from GitHub and press Enter after each command.

      Code snippet
      mkdir ~/projects/risk-management
      cd ~/projects/risk-management/ 
      git clone https://github.com/SAP-samples/extension-suite-learning-journey ./
      Copy code

      The output in the terminal should then look similar to the following. (Currently there are 23 files in the repository. In the future this could differ).

      So the template from GitHub has been cloned successfully. Next, open it in the project explorer.

    3. On the Welcome page, click on Files & Folders.

    4. 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.

    5. On the left side you will now see the content of the risk-management folder:

    6. In Business Application Studio choose TerminalNew Terminal from its menu.

      A new terminal opens in the lower right part of the Business Application Studio screen.

    7. In the terminal, run the command

      Code snippet
      npm ci
      Copy code

      This might take a while. It installs all the dependencies of your project, which are listed in the package.json and package-lock.jsonfile, into a new folder called node_modules within the root of your project. If you encounter messages about Deprecateddependencies ignore them for now, as long as there are no errors in the log.

    8. In the terminal, start a CAP server by typing:

      Code snippet
      cds watch
      Copy code

      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.

    9. 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.

      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 of cds 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.

  2. Add a Data Model to the Project

    Create now a data model using the Core Data Services (CDS) format from CAP.

    1. In the project, go to folder db, representing the data model on the database. In the context menu, select New File.

    2. Enter schema.cds as a name.

    3. Click on the new file in the explorer.

      An editor opens.

    4. Enter the following lines into the editor

      Code snippet
      namespace riskmanagement;
       using { managed } from '@sap/cds/common';
      
       entity Risks : managed {
       key ID : UUID @(Core.Computed : true);
       title : String(100);
       owner : String;
       prio : String(5);
       descr : String;
       miti : Association to Mitigations;
       impact : Integer;
       //bp : Association to BusinessPartners;
       // You will need this definition in a later step
       criticality : Integer;
       }
      
       entity Mitigations : managed {
       key ID : UUID @(Core.Computed : true);
       descr : String;
       owner : String;
       timeline : String;
       risks : Association to many Risks on risks.miti = $self;
       }
      Copy code
    5. Save the file.

      You are using the namespace1riskmanagement. 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, and Mitigations. Each of them has a key called ID and several other properties. A Risk has a mitigation and therefore, the property miti has an association to exactly one Mitigation. A Mitigation in turn can be used for many Risks, 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:

      Notice how cds watch reacted 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.

  3. Add a Service 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 Risksand Mitigations entities, thus the data within the application.

    1. In the project, go to folder srv/, representing the service. In the context menu, select New File.

    2. Enter risk-service.cds as a name.

    3. Click on the new file in the explorer.

      An editor opens.

    4. Enter the following lines into the editor:

      Code snippet
      using { 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;
       //@readonly entity BusinessPartners as projection on rm.BusinessPartners;
       }
      Copy code

      This creates a new service RiskService in the namespace riskmanagement. The annotation @path: 'service/risk' tells the CAP framework to expose the RiskService at URL path service/risk. The service exposes two entities (again, just ignore the commented part for the business partner), Risks and Mitigations, which are both just exposing the entities of the database schema you’ve created in the step before. The @odata.draft.enabled annotation enables edit sessions with draft states2 stored on the server for the UI, that will be added in a later step.

      If you again look at the terminal, you see that cds watch has noticed the new file and now tells us that it serves something:

    5. Press the Open in New Tab button in the lower right corner.

    6. If you are asked to enter a name - just press return.

      You now see this screen:

    7. Click the $metadata link:

      The service already exposes a full-blown OData metadata document.

    8. Go back and click on the Risks link.

      This exposes the data for the Risks entity. Since there are already files in the db/datadirectory containing mock data for the database, you will already see data here.

      Don't close the window, you will need it again.

      Note
      To see the JSON data in a structured way as shown in the screenshot, you require a browser extension. Without such an extension, the data will just be displayed as plaintext without indentations etc.
      Note
      There are a few additional fields like createdAt or modifiedBy which you did not actively define in the entity itself. These were added by CAP, because you added the managed aspect in the entity definition:
      Code snippet
      entity Risks : managed{
          ...
      }
      Copy code
  4. 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.

    1. In the project, go to folder db/ and then into the data/  folder

    2. There is already one file called riskmanagement-Risks.csv:

      Code snippet
      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;
      20466922-7d57-4e76-b14c-e53fd97dcb12;2019-10-24;SYSTEM;SLA violation with possible termination cause;George Gung;2;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;1;Violation of export and trade control with unauthorized downloads;20466921-7d57-4e76-b14c-e53fd97dcb13;200000;
      Copy code
      In a table format, the header and one line of the file content look like the following:
      IDcreatedAtcreatedBytitleownerpriodescrmiti_idimpact
      20466922-7d57-4e76-b14c-e53fd97dcb112019-10-24SYSTEMCFR non-complianceFred Fish3Recent restructuring might violate CFR code 7120466921-7d57-4e76-b14c-e53fd97dcb1110000

    3. There is also another file for the Mitigations entity called riskmanagement-Mitigations.csv.

    4. Click on the file in the explorer:

      Code snippet
      ID;createdAt;createdBy;descr;owner;timeline
       20466921-7d57-4e76-b14c-e53fd97dcb11;2019-10-24;SYSTEM;SLA violation: authorize account manager to offer service credits for recent delivery issues;suitable BuPa;Q2 2020
       20466921-7d57-4e76-b14c-e53fd97dcb12;2019-10-24;SYSTEM;"SLA violation: review third party contractors to ease service delivery challenges; trigger budget review";suitable BuPa;Q3 2020 20466921-7d57-4e76-b14c-e53fd97dcb13;2019-10-24;SYSTEM;Embargo violation: investigate source of shipment request, revoke authorization;SFSF Employee with link possible?;29.03.2020
       20466921-7d57-4e76-b14c-e53fd97dcb14;2019-10-24;SYSTEM;Embargo violation: review shipment proceedure and stop delivery until further notice;SFSF Employee with link possible?;01.03.2020
      Copy code

      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

    Click on the Start button below to open a simulation of the platform. Then follow the step-by-step instructions to create a CAP-based Service

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.

Reference Links: Creating a CAP-Based Service

For your convenience, this section contains the external references in this lesson.

If links are used multiple times within the text, only the first location is mentioned in the reference table.

Ref#SectionContext text fragmentBrief descriptionLink
1Add a Data Model to the ProjectYou are using the namespace riskmanagement.Using namespaceshttps://cap.cloud.sap/docs/guides/domain-models#using-namespaces
2Add a Service to the Projectannotation enables edit sessions with draft statesDraft-based editinghttps://cap.cloud.sap/docs/advanced/fiori#draft-support

Save progress to your learning plan by logging in or creating an account