Skip to Content

Build a CAP Application

This guide is a step-by-step walkthrough to build a CAP Node.js or Java application.
You will learn
  • How to create a CAP project
  • How to add a domain model
  • How to create services
  • How to add data to your database
slavipandeSvetoslav PandelievJanuary 31, 2025
Created by
slavipande
October 4, 2023
Contributors
ekaterina-mitova
hm23
slavipande

Prerequisites

You have configured the SAP Business Application Studio. Follow the steps in the Set Up SAP Business Application Studio for Development tutorial that is part of the Develop a Full-Stack CAP Application Following SAP BTP Developer’s Guide tutorial group.

This tutorial follows the guidance provided in the SAP BTP Developer’s Guide.

  • Step 1

    You can create a CAP project in either Node.js or Java. You have to choose one way or the other and follow through. The tabs Node.js and Java provide detailed steps for each alternative way.

  • Step 2
    1. In the db folder, create a new schema.cds file.

    2. Paste the following code snippet in the schema.cds file.

      CDS
      Copy
      using { cuid, managed, sap.common.CodeList } from '@sap/cds/common';
      namespace sap.capire.incidents; 
      
      /**
      * Incidents created by Customers.
      */
      entity Incidents : cuid, managed {  
      customer     : Association to Customers;
      title        : String  @title : 'Title';
      urgency        : Association to Urgency default 'M';
      status         : Association to Status default 'N';
      conversation  : Composition of many {
          key ID    : UUID;
          timestamp : type of managed:createdAt;
          author    : type of managed:createdBy;
          message   : String;
      };
      }
      
      /**
      * Customers entitled to create support Incidents.
      */
      entity Customers : managed { 
      key ID        : String;
      firstName     : String;
      lastName      : String;
      name          : String = firstName ||' '|| lastName;
      email         : EMailAddress;
      phone         : PhoneNumber;
      incidents     : Association to many Incidents on incidents.customer = $self;
      creditCardNo  : String(16) @assert.format: '^[1-9]\d{15}$';
      addresses     : Composition of many Addresses on addresses.customer = $self;
      }
      
      entity Addresses : cuid, managed {
      customer      : Association to Customers;
      city          : String;
      postCode      : String;
      streetAddress : String;
      }
      
      entity Status : CodeList {
      key code: String enum {
          new = 'N';
          assigned = 'A'; 
          in_process = 'I'; 
          on_hold = 'H'; 
          resolved = 'R'; 
          closed = 'C'; 
      };
      criticality : Integer;
      }
      
      entity Urgency : CodeList {
      key code: String enum {
          high = 'H';
          medium = 'M'; 
          low = 'L'; 
      };
      }
      
      type EMailAddress : String;
      type PhoneNumber : String;
      

    What happens here?

    The provided CDS code snippet defines several entities and their relationships.

    The Incidents entity represents incidents created by customers, with fields for customer, title, urgency, status, and a composition of many conversations. Each conversation has an ID, timestamp, author, and message.

    The Customers entity represents customers who can create support incidents. It includes fields for ID, first name, last name, email, phone, credit card number, and a composition of many addresses. The name field is calculated from the firstName and lastName fields. Elements can be specified with a calculation expression, in which you can refer to other elements of the same entity. These calculated elements are used for convenience. For more information, see Calculated Elements.

    The Addresses entity represents the addresses of customers, with fields for customer, city, postcode, and street address.

    The Status and Urgency entities represent the status and urgency of incidents, respectively. Both are of type CodeList and include a code field with a set of predefined values.

    The EMailAddress and PhoneNumber are defined as types of String.

    The code also includes the use of cuid and managed from @sap/cds/common, which are common features for defining entities in CDS. The cuid feature provides a unique identifier for an entity, while managed adds common administrative fields such as createdAt and createdBy.

  • Step 3

    It’s a good practice in CAP to create single-purposed services. Hence, let’s define a ProcessorService for support engineers to process incidents created by customers and an AdminService for administrators to perform admin activities such as analysing audit logs.

    To create the services’ definition:

  • Step 4

    Since we already have an SQLite in-memory database that was automatically created in the previous step, let’s now fill it with some test data.

    1. Run the following command in the incident-management root folder of your project:

      bash
      Copy
      cds add data
      
    2. Check the output.

      bash
      Copy
      Adding feature 'data'...
      Creating db/data/sap.capire.incidents-Addresses.csv
      Creating db/data/sap.capire.incidents-Customers.csv
      Creating db/data/sap.capire.incidents-Incidents.csv
      Creating db/data/sap.capire.incidents-Incidents.conversation.csv
      Creating db/data/sap.capire.incidents-Status.csv
      Creating db/data/sap.capire.incidents-Status.texts.csv
      Creating db/data/sap.capire.incidents-Urgency.csv
      Creating db/data/sap.capire.incidents-Urgency.texts.csv
      
      Successfully added features to your project.
      

      You can find the generated CSV templates within the db folder, in a newly-created data folder.

  • Step 5

    Important consideration for test data

    In the previous step, you added several CSV files with test data. These files are required to pre-fill the SQLite memory with data for local testing. This is most suitable for development environments, where schema changes are very frequent and broad.

    When you redeploy your database, it will always delete all tables and views and create them from scratch. This behaviour is known as drop-create.

    • Test files should never be deployed to an SAP HANA production database as table data.

      In such cases, changing a data file can cause the deletion of all files of affected database tables, even if the data files for the affected tables have been removed before. SAP HANA remembers all data files that have ever been deployed to the tables and might restore them.

      Only master data files should be delivered in this way. Master data files are files, which are defined by the application developer and can’t be changed by the application. Examples for master data include country codes, status codes and criticality, and urgency codes and descriptions.

      Delivering files for tables with customer data will cause data loss in productive scenarios! See section Providing Initial Data in the CAP documentation for more details.

    • Drop-create is most appropriate for development. However, drop-create isn’t suitable for database upgrades in production, as all customer data would be lost. To avoid this, cds deploy also supports automatic schema evolution. See section Schema Evolution.

    Replace the respective generated CSV templates with the following content:

    • db/data/sap.capire.incidents-Addresses.csv:

      csv
      Copy
      ID,customer_ID,city,postCode,streetAddress
      17e00347-dc7e-4ca9-9c5d-06ccef69f064,1004155,Rome,00164,Piazza Adriana
      d8e797d9-6507-4aaa-b43f-5d2301df5135,1004161,Munich,80809,Olympia Park
      ff13d2fa-e00f-4ee5-951c-3303f490777b,1004100,Walldorf,69190,Dietmar-Hopp-Allee
      
    • db/data/sap.capire.incidents-Customers.csv:

      csv
      Copy
      ID,firstName,lastName,email,phone
      1004155,Daniel,Watts,daniel.watts@demo.com,+39-555-123
      1004161,Stormy,Weathers,stormy.weathers@demo.com,+49-020-022
      1004100,Sunny,Sunshine,sunny.sunshine@demo.com,+49-555-789
      
    • db/data/sap.capire.incidents-Incidents.conversation.csv:

      csv
      Copy
      ID,up__ID,timestamp,author,message
      2b23bb4b-4ac7-4a24-ac02-aa10cabd842c,3b23bb4b-4ac7-4a24-ac02-aa10cabd842c,1995-12-17T03:24:00Z,Harry John,Can you please check if battery connections are fine?
      2b23bb4b-4ac7-4a24-ac02-aa10cabd843c,3a4ede72-244a-4f5f-8efa-b17e032d01ee,1995-12-18T04:24:00Z,Emily Elizabeth,Can you please check if there are any loose connections?
      9583f982-d7df-4aad-ab26-301d4a157cd7,3583f982-d7df-4aad-ab26-301d4a157cd7,2022-09-04T12:00:00Z,Sunny Sunshine,Please check why the solar panel is broken.
      9583f982-d7df-4aad-ab26-301d4a158cd7,3ccf474c-3881-44b7-99fb-59a2a4668418,2022-09-04T13:00:00Z,Bradley Flowers,What exactly is wrong?
      
    • db/data/sap.capire.incidents-Incidents.csv:

      csv
      Copy
      ID,customer_ID,title,urgency_code,status_code
      3b23bb4b-4ac7-4a24-ac02-aa10cabd842c,1004155,Inverter not functional,H,C
      3a4ede72-244a-4f5f-8efa-b17e032d01ee,1004161,No current on a sunny day,H,N
      3ccf474c-3881-44b7-99fb-59a2a4668418,1004161,Strange noise when switching off Inverter,M,N
      3583f982-d7df-4aad-ab26-301d4a157cd7,1004100,Solar panel broken,H,I
      
    • db/data/sap.capire.incidents-Status.csv:

      csv
      Copy
      code;descr;criticality
      N;New;3
      A;Assigned;2
      I;In Process;2
      H;On Hold;3
      R;Resolved;2
      C;Closed;4
      
    • db/data/sap.capire.incidents-Urgency.csv:

      csv
      Copy
      code;descr
      H;High
      M;Medium
      L;Low
      

      Notice that cds add data created eight files, while we’re adding data to just six of them. We’re leaving the files sap.capire.incidents-Status.texts.csv and sap.capire.incidents-Urgency.texts.csv empty because they hold translated text that will be filled once the application is localized and translations are created.

    Upon detecting these new files, the CAP server prints a message stating that the content of the files has been filled into the database automatically:

    When you revisit the Incidents or the Customers endpoint, you might see something like this instead of the nicely formatted output from above.

    No JSON Viewer

    However, this doesn’t mean you’ve made a mistake in the tutorial. Rather, this is the correct output without any formatting. If you’d like to see a formatted output in your browser, you can add an extension to your browser. Here are a few exemplary JSON formatters for different browsers:

    It's a good practice in CAP to create single-purposed services.

Back to top