Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
TiaXu
Product and Topic Expert
Product and Topic Expert

Overview


Common




  • Import API Definition with cds import


Database




  • Compile CDS Models to Different Outputs with cds compile

  • Persist Data by Deploying to SQLite with cds deploy --to sqlite

  • Add HANA Configuration with cds add hana

  • Persist Data by Deploying to HANA with cds deploy –-to hana


Security




  • Generate XSUAA Deploy Configuration with cds add xsuaa Based on CDS Annotations

  • Update XSUAA Deploy Configuration with cds compile


MTA




  • Generate Deploy Configuration with cds add mta Based on package.json


Fiori Tools




  • Add Deployment Configuration with fiori add deploy-config




Common


Import API Definition with cds import


The first thing you need to do is to get the XML files (EDM XML – Entity Data Model XML – in short EDMX) which define the entities that compose the OData services to be consumed in the application. You can get such files from SAP API Business Hub.


Import the API to your project using cds import.



cds import srv/<api-definition-file-name>.edmx

This adds the API in CSN (Core Schema Notation) format to the srv/external folder and also copies the EDMX file into that folder. You can see the content is nothing else than a JSON representation of the service metadata with the description of the entities contained in it. This JSON is used by the CDS framework to let you make type-safe OData calls to the service in the form of simple queries via the easy-to-use low-code CDS Query Language (CQL).


Additionally, for Node.js it adds the API as an external OData service to your package.json.




"cds": {
"requires": {
    "API_BUSINESS_PARTNER": {
        "kind": "odata-v2",
        "model": "srv/external/API_BUSINESS_PARTNER"
    }
}
}


You use this declaration later to connect to the remote service using a destination. A destination should be created in the Cockpit called e.g. S4HANA.




"cds": {
"requires": {
"API_BUSINESS_PARTNER": {
"kind": "odata",
"model": "srv/external/API_BUSINESS_PARTNER",
"[production]": {
"credentials": {
"destination": "S4HANA",
"path": "/sap/opu/odata/sap/API_BUSINESS_PARTNER"
}
}
}
}
}


Alternatively, you can set the options and flags for cds import in the .cdsrc.json file in your project root:


For example:




{
"import": {
"as": "cds",
"force": true,
"include_namespaces": "sap,c4c"
}
}


Now run cds import <file-name>



Database


Compile CDS Models to Different Outputs with cds compile


cds compile db/ --to sql
cds compile db/ --to json
cds compile db/ --to yml
...

Or,



cds db/ -2 sql
cds db/ -2 json
cds db/ -2 yml
...


Currently supported:



- json, yml
- edm, edmx, edmx-v2, edmx-v4, edmx-w4, edmx-x4
- sql, hdbcds, hdbtable
- cdl [beta]
- xsuaa
- openapi


For example: cds compile db/ --to sql




CREATE TABLE sap_ui_riskmanagement_Risks (
createdAt TIMESTAMP_TEXT,
createdBy NVARCHAR(255),
modifiedAt TIMESTAMP_TEXT,
modifiedBy NVARCHAR(255),
ID NVARCHAR(36) NOT NULL,
title NVARCHAR(100),
prio NVARCHAR(5),
descr NVARCHAR(5000),
miti_ID NVARCHAR(36),
impact INTEGER,
criticality INTEGER,
PRIMARY KEY(ID)
);

CREATE TABLE sap_ui_riskmanagement_Mitigations (
createdAt TIMESTAMP_TEXT,
createdBy NVARCHAR(255),
modifiedAt TIMESTAMP_TEXT,
modifiedBy NVARCHAR(255),
ID NVARCHAR(36) NOT NULL,
description NVARCHAR(5000),
owner NVARCHAR(5000),
timeline NVARCHAR(5000),
PRIMARY KEY(ID)
);


Persist Data by Deploying to SQLite with cds deploy --to sqlite


Instead of using in-memory, we can also use persistent databases, e.g. SQLite. The difference from the automatically provided in-memory database is that we now get a persistent database stored in the local file ./sqlite.db. This is also recorded in the package.json.



cds deploy --to sqlite

Then we can use the sqlite3 CLI to query with the newly created database:



sqlite3 sqlite.db .dump
sqlite3 sqlite.db .tables

Add HANA Configuration with cds add hana


Some configurations should be added in order to use HANA as the database.



cds add hana


In the package.json file, dependency and cds requires will be added:



{
...
"dependencies": {
...
"hdb": "^0.19.0"
},
...
"cds": {
"requires": {
...
"db": {
"kind": "hana-cloud"
}
}
}
}


Or, you can add HANA configuration for production:



cds add hana --for production


In the package.json file, dependency and cds requires will be added:



{
...
"dependencies": {
...
"hdb": "^0.19.0"
},
...
"cds": {
"requires": {
...
"[production]": {
"db": {
"kind": "hana-cloud"
}
},
"db": {
"kind": "sql"
}
}
}
}


Or, you can add HANA configuration for hybrid mode:



cds add hana --for hybrid

Persist Data by Deploying to HANA with cds deploy –-to hana


cds deploy lets you deploy just the database parts of the project to an SAP HANA instance. The server application (the Node.js or Java part) still runs locally and connects to the remote database instance, allowing for fast development roundtrips.



cds deploy –-to hana
cds watch




cds deploy does the following behind:





  1. Build the database artifacts from the CAP project in the gen folder that’s created under the project root folder, for further deployment to SAP HANA Cloud.




  2. Create a service instance of type SAP HANA Schemas & HDI Containers with the hdi-shared plan, that handles the HDI container




  3. Create the SAP HANA database artifacts from the application inside the HDI container




  4. Bind the service instance to the local project by modifying the default-env.json file, adding the database credentials (actually the service key from the service binding).





Or, in the hybrid mode:



cds deploy –-to hana --profile hybrid
cds watch --profile hybrid

Security


Generate XSUAA Deploy Configuration with cds add xsuaa Based on CDS Annotations


cds add xsuaa
cds add xsuaa --for production


cds add xsuaa does the following behind:





  • Adds the XSUAA service to the package.json file of your project




  • Creates the XSUAA security configuration xs-security.json for your project with roles/scopes derived from authorization-related annotations in your CDS models.




Ensure to rerun cds compile --to xsuaa, as documented in the Authorization guide whenever there are changes to these annotations.



Update XSUAA Deploy Configuration with cds compile


Ensure to rerun cds compile --to xsuaa, as documented in the Authorization guide whenever there are changes to these annotations.



cds compile srv/ --to xsuaa > xs-security.json


{
"scopes": [
{
"name": "$XSAPPNAME.Admin",
"description": "Admin"
}
],
"role-templates": [
{
"name": "Admin",
"description": "generated",
"scope-references": [
"$XSAPPNAME.Admin"
],
"attribute-references": []
}
]
}

Then, use cf create-service xsuaa application <servicename> -c xs-security.json to create the XSUAA service with the XSUAA configuration, or cf update-service <servicename> -c xs-security.json to update the configuration.



MTA


Generate Deploy Configuration with cds add mta Based on package.json


To deploy your application to Cloud Foundry on SAP BTP, you are going to use the MTA (Multi-Target Application) approach, which facilitates the deployment as it pushes everything at once to the platform with file mta.yaml: UI application, backend service, database, service instances creation and binding, etc.


Let the CAP server generate an initial mta.yaml file. The file is generated based on your previously created settings in the package.json file.



cds add mta

For example:




package.json:



{
"name": "cpapp",
"version": "1.0.0",
"description": "A simple CAP project.",
"repository": "<Add your repository here>",
"license": "UNLICENSED",
"private": true,
"dependencies": {
"@sap/cds": "^6",
"@sap/xssec": "^3.2.8",
"express": "^4",
"passport": "^0.5.0",
"hdb": "^0.19.0"
},
"devDependencies": {
"@sap/ux-specification": "^1.90.12",
"sqlite3": "^5.0.2"
},
"engines": {
"node": "^16"
},
"scripts": {
"start": "cds run",
"watch-risks": "cds watch --open risks/webapp/index.html#fe-lrop-v4",
"watch-mitigations": "cds watch --open mitigations/webapp/index.html#fe-lrop-v4"
},
"eslintConfig": {
"extends": "eslint:recommended",
"env": {
"es2020": true,
"node": true,
"jest": true,
"mocha": true
},
"globals": {
"SELECT": true,
"INSERT": true,
"UPDATE": true,
"DELETE": true,
"CREATE": true,
"DROP": true,
"CDL": true,
"CQL": true,
"CXL": true,
"cds": true
},
"rules": {
"no-console": "off",
"require-atomic-updates": "off"
}
},
"sapux": [
"app/risks",
"app/mitigations"
],
"cds": {
"requires": {
"[production]": {
"db": {
"kind": "hana-cloud"
},
"auth": {
"kind": "xsuaa"
}
},
"db": {
"kind": "sql"
},
"uaa": {
"kind": "xsuaa",
"credentials": {}
}
}
}
}

Generated mta.yaml:



---
_schema-version: '3.1'
ID: cpapp
version: 1.0.0
description: "A simple CAP project."
parameters:
enable-parallel-deployments: true
build-parameters:
before-all:
- builder: custom
commands:
- npx -p @sap/cds-dk cds build --production

modules:
- name: cpapp-srv
type: nodejs
path: gen/srv
parameters:
buildpack: nodejs_buildpack
build-parameters:
builder: npm-ci
provides:
- name: srv-api # required by consumers of CAP services (e.g. approuter)
properties:
srv-url: ${default-url}
requires:
- name: cpapp-db
- name: cpapp-auth

- name: cpapp-db-deployer
type: hdb
path: gen/db
parameters:
buildpack: nodejs_buildpack
requires:
- name: cpapp-db

resources:
- name: cpapp-db
type: com.sap.xs.hdi-container
parameters:
service: hana
service-plan: hdi-shared
- name: cpapp-auth
type: org.cloudfoundry.managed-service
parameters:
service: xsuaa
service-plan: application
path: ./xs-security.json
config:
xsappname: cpapp-${org}-${space}
tenant-mode: dedicated

The mta.yaml file consists of different modules (Cloud Foundry apps) and resources (Cloud Foundry services):



modules



  • cpapp-srv - OData service




  • cpapp-db-deployer - Deploy CAP schema and data (CSV files) to database




resources

The resources are generated from the requires section of cds in the package.json.





  • cpapp-db - SAP HANA DB HDI container




  • cpapp-uaa - XSUAA service




The resources are Cloud Foundry service instances that are automatically created and updated during the MTA deployment.



Fiori Tools


Add Deployment Configuration with fiori add deploy-config


npm install --global @sap/ux-ui5-tooling
npm install --global @sap/generator-fiori
cd app/<appname>
fiori add deploy-config cf

For example:




mta.yaml:



_schema-version: "3.1"
ID: sfsf-projman
description: A simple CAP project.
version: 1.0.0
modules:
- name: sfsf-projman-srv
type: nodejs
path: gen/srv
requires:
- name: sfsf-projman-db
- name: sfsf-projman_html_repo_host
- name: sfsf-projman-destination-service
provides:
- name: srv-api
properties:
srv-url: ${default-url}
parameters:
buildpack: nodejs_buildpack
build-parameters:
builder: npm-ci
- name: sfsf-projman-db-deployer
type: hdb
path: gen/db
requires:
- name: sfsf-projman-db
parameters:
buildpack: nodejs_buildpack
- name: sfsf-projman-destination-content
type: com.sap.application.content
requires:
- name: sfsf-projman-destination-service
parameters:
content-target: true
- name: sfsf-projman_html_repo_host
parameters:
service-key:
name: sfsf-projman_html_repo_host-key
- name: uaa_sfsf-projman
parameters:
service-key:
name: uaa_sfsf-projman-key
parameters:
content:
instance:
destinations:
- Name: sfsf_projman_tia_sfsf_projman_html_repo_host
ServiceInstanceName: sfsf-projman-html5-app-host-service
ServiceKeyName: sfsf-projman_html_repo_host-key
sap.cloud.service: sfsf-projman-tia
- Authentication: OAuth2UserTokenExchange
Name: sfsf_projman_tia_uaa_sfsf_projman
ServiceInstanceName: sfsf-projman-xsuaa-service
ServiceKeyName: uaa_sfsf-projman-key
sap.cloud.service: sfsf-projman-tia
existing_destinations_policy: ignore
build-parameters:
no-source: true
resources:
- name: sfsf-projman-db
type: com.sap.xs.hdi-container
parameters:
service: hana
service-plan: hdi-shared
- name: sfsf-projman-destination-service
type: org.cloudfoundry.managed-service
parameters:
config:
HTML5Runtime_enabled: true
version: 1.0.0
service: destination
service-name: sfsf-projman-destination-service
service-plan: lite
- name: sfsf-projman_html_repo_host
type: org.cloudfoundry.managed-service
parameters:
service: html5-apps-repo
service-name: sfsf-projman-html5-app-host-service
service-plan: app-host
- name: uaa_sfsf-projman
type: org.cloudfoundry.managed-service
parameters:
path: ./xs-security.json
service: xsuaa
service-name: sfsf-projman-xsuaa-service
service-plan: application
parameters:
enable-parallel-deployments: true
build-parameters:
before-all:
- builder: custom
commands:
- npx -p @sap/cds-dk cds build --production

In the mta.yaml, two modules related to the SAP Fiori app are added:



- name: sfsf-projman-app-content
type: com.sap.application.content
path: .
requires:
- name: sfsf-projman_html_repo_host
parameters:
content-target: true
build-parameters:
build-result: resources
requires:
- artifacts:
- sfsfprojmansfsfprojman.zip
name: sfsfprojmansfsfprojman
target-path: resources/
- name: sfsfprojmansfsfprojman
type: html5
path: app/sfsf-projman
build-parameters:
build-result: dist
builder: custom
commands:
- npm install
- npm run build:cf
supported-platforms: []

In the mta.yaml, parameters and requires are added:



- name: sfsf-projman-destination-service
type: org.cloudfoundry.managed-service
parameters:
  config:
    HTML5Runtime_enabled: true
    init_data:
      instance:
        destinations:
        - Authentication: NoAuthentication
          Name: ui5
          ProxyType: Internet
          Type: HTTP
          URL: https://ui5.sap.com
        - Authentication: NoAuthentication
          HTML5.DynamicDestination: true
          HTML5.ForwardAuthToken: true
          Name: sfsf-projman-srv-api
          ProxyType: Internet
          Type: HTTP
          URL: ~{srv-api/srv-url}
        existing_destinations_policy: update
    version: 1.0.0
  service: destination
  service-name: sfsf-projman-destination-service
  service-plan: lite
requires:
- name: srv-api

xs-app.json file will be created, which holds the configuration of the routes to be mapped by the approuter to point to the destination of the backend service.



{
"welcomeFile": "/index.html",
"authenticationMethod": "route",
"routes": [
  {
    "source": "^/projman/(.*)$",
    "target": "/projman/$1",
    "destination": "sfsf-projman-srv-api",
    "authenticationType": "xsuaa",
    "csrfProtection": false
  },
  {
    "source": "^/resources/(.*)$",
    "target": "/resources/$1",
    "authenticationType": "none",
    "destination": "ui5"
  },
  {
    "source": "^/test-resources/(.*)$",
    "target": "/test-resources/$1",
    "authenticationType": "none",
    "destination": "ui5"
  },
  {
    "source": "^(.*)$",
    "target": "$1",
    "service": "html5-apps-repo-rt",
    "authenticationType": "xsuaa"
  }
]
}

ui5-deploy.yaml file will be created:



# yaml-language-server: $schema=https://sap.github.io/ui5-tooling/schema/ui5.yaml.json
specVersion: '2.4'
metadata:
name: sfsf.projman.sfsfprojman
type: application
resources:
configuration:
  propertiesFileSourceEncoding: UTF-8
builder:
resources:
  excludes:
    - "/test/**"
    - "/localService/**"
customTasks:
- name: webide-extension-task-updateManifestJson
  beforeTask: generateManifestBundle
  configuration:
    appFolder: webapp
    destDir: dist
- name: ui5-task-zipper
  afterTask: generateCachebusterInfo
  configuration:
    archiveName: sfsfprojmansfsfprojman
    additionalFiles:
    - xs-app.json

And, some other configuration will be added in the package.json and manifest.json files.


4 Comments