Skip to Content
Technical Articles

SAP Cloud Platform Backend service: Tutorial [12]: CDS : local: build

This blog is part of a series of tutorials explaining the usage of SAP Cloud Platform Backend service in detail.

Note:
This blog is fully optional
For using Backend service, you don’t need to do anything locally
Continue reading to know why this blog is still useful for you.
Or skip this blog to save 12 minutes

Quicklinks:
Installation
Usage
Reference

 

Have you ever wondered what is happening after you press CREATE in the Backend service?
Oh, how interesting
Don’t worry, you won’t learn it in this blog.
Oh, how disappointing
However, on the other hand, this blog is not completely useless:
It shows you one little step of what happens under the hood, when creating an API

As you know, Backend service is meant to make your life easier.
You only need to give a CDS model, then many things happen automatically and at the end you have an OData service
We already know: from the CDS model, a database is created and a service is created (to access the database remotely)
In order to create e.g. a database, a database-specific definition is required, and needs to be derived from the CDS model
This process, generating the specific artifacts from the CDS model,  is called “compilation”
Also known as “CDS build”.
CDS comes with a couple default builders.

For example:
One builder is invoked to convert the CDS model into an OData model. The OData model (edmx) is then the basis for the generation of the OData service itself

The CDS build is triggered in Backend service after uploading a CDS file.

In this blog, we’re going to learn how to invoke the CDS build locally

Why should I do local build? I’m happy that everything is in the cloud!
One reason: It can help to speed up development turnarounds.
While developing CDS models, I assume you’ve already experienced that you upload your model file to Backend service, wait some time and then realize that your API is not created, due to a compilation error, due to an erroneous CDS file.

To discover the error, you need to open the “Deployment Logs” dialog and refresh it
Too many clicks to find the error in the CDS model
But I have a CDS-aware IDE (I learned from this fantastic blog)
Yes, thanks, if you use WebIDE or Visual  Studio Code with CDS plugin, it safes lot of time with its language support, validation markers, etc
But nevertheless there are errors which only are detected by the CDS compiler
An example is described in this (fantastic) blog

 

As such, after modelling your CDS model, before uploading to Backend service, you can quickly perform a local build of the CDS, to verify if there are errors
The local build is easy to perform and extremely fast.

One more reason:
It helps to understand what’s happening under the hood.
As such, it can help to find the reason if your API behaves other than expected
If you’re familiar with OData, you can run the CDS build in order to get the edmx-file before uploading to Backend service. Which enables you (or your UI developer) to view if the resulting edmx is like expected
Wrt HANA, you can run the CDS build to check the generated hana definition files (.hdbcds), to view and understand the table distribution

Need more reasons?
Well, I don’t have but if you find more reasons, please post them in the comment section

Warning:
Before you go ahead, please be advised that the CDS build tool is a command-line tool

Sounds scary…😨

Prerequisites

In order to run the CDS build on your local machine, you need the following prerequisites:

  • Node.js with configured registry
  • CDS tool

 

Install CDS Command-Line Tools

I’m still scared

Running the CDS build on your local laptop is easy, although it sounds a bit scary because the CDS tool is based on node.js and the build is triggered on the command line

First Step: install node.js

Already installed?
If you have node.js installed on your machine, make sure that you have the minimum required version, which is 8.9.0
Also, you need to configure the SAP registry (see below)

Not yet installed?
Go to the node.js homepage , download the stable release (“Recommended for most users”) and follow the installation instructions,
You might need to restart your computer

After installation, you can verify if node.js is up and running:
Open a command prompt and type:  node -v
It should respond with a version information and no error message

Second step: configure SAP registry

The CDS tool is installed via the “node.js package manager (npm)”
npm itself doesn’t need to be installed separately, it is already on your computer if you have installed node.js
You can verify by executing npm -v on your command line

The great advantage of using a package manager:
If you want to install something, you don’t need to go to the http://something-website, then download and install and configure, etc
No.
No?
No.
You just tell the package manager to install.
And he does?
Yes
How do I tell?
Politely. Using the respective command, like:
npm install <yourTool>
A dream
Stop, you need to wake up for a second
…yawn…

A little prerequisite is required:
npm knows almost everything
It does so, because it has a pre-configured registry
However, the CDS tool is not contained in that registry because SAP maintains its own registry: https://npm.sap.com

As such, if we want to install CDS tool, we have to tell npm to look into the SAP registry as well
With other words: we have to configure npm

npm has a central configuration file (.npmrc), it is located in your user directory and can be edited directly:

Alternatively, use an npm-command on the command-line.
But read the note before you proceed:

Note-before-you-proceed:
If you already have an @sap:registry entry in your registry, it will be replaced
If you don’t want your entry to be replaced, you can add comments:
//@sap:registry=yourOldEntry

To add the SAP npm registry, go to your command shell and type the following command

npm set @sap:registry=https://npm.sap.com

The result:

I see nothing?
Yes, same on my side.

Third step: install CDS tools

Now, to install the CDS tools, you can enter the following command in your command prompt:

npm install -global @sap/cds

This command installs the CDS tool in your home directory.
The install command uses an optional parameter: -global
This is a convenient way of installing node packages: they are made available globally

Cool, it is really available everywhere?
Yes, cool, it is available globally on your local laptop
Can I skip that option?
Yes, if you remove the -global, then the CDS tool is installed in the current directory (the directory from where you execute the install command in the command prompt)
However, if you do so, you have to use always fully qualified path when using the CDS tool

OK, the CDS tool is installed, you can now verify if the installation has been successful
Just type cds somewhere in the command prompt

The result is: (almost) nothing
The usage of the cds command is wrong, so it prints the help content

That’s ok for us, we just wanted to know if it has been installed successfully

 

Run the CDS tool

Cool – and what can I do with the CDS command-line tools?
As mentioned above: we can build
With other words: we can compile
Are there more other words?
What about:
We can convert, we can transform, we can translate…
Yes, we can
Yes, ok, let’s try it.

The compile command

Create a folder, e.g. C:\CDS, and copy one of your CDS model files into it.
If you don’t have a CDS model file at hand, you can use the one in the appendix section at the end of this blog.
Then open a command prompt in that folder
Execute the CDS command as follows:

cds compile <yourModel>.cds

Example:

cds compile MyFirstService.cds

Note:
The compile command requires the model file as first parameter
The model file can be fully qualified or relative path

Note:
The compile command is the default cds command.
As such, you can omit it and just type
cds MyFirstService.cds

The result:

What is it?
As per default, the compile command translates the CDS format to CSN format.
CSN stands for “Core Schema Notation”

I understand CSN as a kind of totally generic representation of a model, as such ideal for being interpreted by machines, means, programmatically, and ideal for sharing (interchanging) model definitions. I mean, starting from CSN, a tool can generate whatever you want, for example edmx

Even though it looks beautiful, this CSN notation is not meant to be read by humans.
So if you’re a human, you should read below chapters to learn how to generate other output than CSN

Note:
CSN has a special pronunciation: instead of pronouncing each character separately, like “See Es En”, you would just say “SeeSn”
Using this pronunciation, you’ll feel like professional  and you can impress your boss and your family

 

Test-compile an erroneous model

Even though we don’t want to read the CSN output of the compile command, that is enough for us.
Remember that we use the local CDS build just for verification of our model.
It saves  time because we don’t upload to Backend service

So let’s try this effect: let’s introduce an error in our CDS model

Most easily, this can be achieved by removing the semicolon after the first property:

Example:

entity Products {  
   key ProductId : Integer  
   Name : String;   
   . . .

After executing the compile command we get below result:

 

Validate OData model

Above example is nice, but not enough.
It captures errors in the CDS model itself.
It captures even errors which are not marked by the CDS editor language support

However, there can be requirements which can be mandatory by the target but not in CDS.
Like that causing the CDS build to fail. Not due to erroneous CDS, but errors in the target format.
As such, in our compile command, we need to express the target.

Let’s see a few examples for possible targets.

Until now, we’ve compiled the CDS to CSN
The seesn output was represented as plain Javascript object

We can specify the representation as json or yml:

cds MyFirstService.cds --to yml

 

Now try the following command:

cds MyFirstService.cds --to edmx

This will produce the OData model.
Now we can do the following test:
The following model looks nice – but has an error:

service MyFirstService{
   entity Products {
      ProductId : Integer;
      Name : String;
      Category : String;
   }
}

The CDS support in the CDS editor doesn’t see an error here.
If you compile to CSN, no error is dumped
But if you compile to edmx, then you get an error message:

“Entity … does not have a key…”

The same error you would get when uploading to Backend service, but it would take much more time to discover it

===> Finally, now you can see how useful the local build can be. <===
. . .
===> Finally, now you can see how useful the local build can be. <===
. . .
===> Finally, now …
ok, ok….really useful

 

Some more interesting stuff

In this section we will view the database table definition file(s).

CDS comes with the required processors for the (currently) relevant target backends
This is the reason why we can just compile to OData without downloading additional node.js packages

One more interesting target is the database. Currently HANA is used and that is also the name of the processor

cds MyFirstService.cds  --to hana

The result is the HANA specific definition used for generating the database table

Another example:

cds MyFirstService.cds  --to sql

 

OData example:
We’ve already compiled CDS to OData, but we haven’t talked about the 2 different protocol versions: OData V2 and OData V4
How do we express the version?
It is done as follows:

OData V2:

cds MyFirstService.cds  --to edmx

OData V4:

cds MyFirstService.cds  --to edm

As you can see, OData V4 supports metadata document to be represented in JSON, which is leveraged by the CDS compiler

 

Some more less interesting stuff

I’d like to write to file system

Above we’ve mentioned the “HANA specific definition”
The way of wording was chosen to avoid saying “specific HANA definition files”
Oh, I would have asked: which files?
Yes, that’s what I wanted to avoid.
The following command-line option will answer your question

cds MyFirstService.cds --to hana --dest hanaDefinitionFolder

the option –dest  allows to specify a folder (will be created if not existing)

Instead of dumping the converted model to the console, CDS will then create a file with proper file extension, in the specified destination folder

See below for an example:

You can see that the hana definition files are created for each table (resp. entity) and with file extension .hdbcds
If you know HANA from the past, you might have seen such files already.

Furthermore, writing the compiled artifacts to file system is helpful if you need to troubleshoot bigger models

Some last and totally uninteresting stuff

Are there abbreviations?

The more familiar you get with typing commands on the command line, the more you wish to save time while typing
The CDS command-line tools have foreseen your wish and come up with abbreviations

As such, the following full command

cds compile MyFirstService.cds  --to edmx

can be shortened to

cds MyFirstService.cds  -2 edmx

Again, this helps to save time and to impress your boss

Another abbreviation: -o instead of –dest

The full list of options supported by the compile command can be viewed when invoking the help:

cds compile --help

Here in the dumped help you can see all options and the corresponding abbreviations

We’ve been talking about targets, is there a full reference?

-2 yml
-2 yaml
-2 json
-2 cdl
-2 sql
-2 hana
-2 emdx
-2 edm
-2 annos
-2 swgr

Note:
annos is used to generate a separate xml containing only the annotations. Such xml file can be consumed by the annotation editor in WebIDE
swgr is the abbreviation of openAPI (there must be some nostalgy using this abbreviation…)
cdl stands for CDS Definition Language

Exercises

I’ve thought of a little exercise for you – it is nonsense, but you can take it as a challenge and write your result in the comment section 😉

Are they difficult?
No no
Is there a solution at the end?
No no, not necessary

 

Exercise 1

Take your preferred CDS file
Create an API based on that CDS file
Take your preferred CDS file again
Convert it to edmx using the CDS compiler
Create an API based on that edmx file

Finally, you’ve created 2 APIs which should be identical

Question:
Are they?

Exercise 2

Create a CDS model which contains a structured custom type.
Then run the CDS compiler to generate the HANA .hdbcds file(s)
View the file(s).

Question:
What do you observe?

Hint: View this blog

Exercise 3

Create a CDS model which contains a managed association.
Then run the CDS compiler to generate the HANA .hdbcds file(s)
View the file(s).

What do you observe?

Summary

In this tutorial you‘ve gained deeper understanding about CDS and about the Backend service
You’ve seen the CDS compiler in action
You’ve understood a little piece of what is happening when you upload a CDS file to  Backend service to create an API

Links

About SAP npm registry:

announcement blog

There’s also an info section in the SAP help

CDS tool documentation can be found here

 

Appendix: Sample CDS model

File: MyFirstService.cds

service MyFirstService{
   entity Products {  
      key ProductId : Integer;                
      Name : String;                
      Category : String;
   }
}

 

Reference: CDS commands

// help: built-in reference
cds compile --help

// compile command
cds compile MyFirstService.cds

// with target
cds MyFirstService.cds --to edmx

// with destination folder
cds compile MyFirstService.cds --to hana --dest hanaDefinitionFolder

// abbreviations and omitting the 'compile' param
cds MyFirstService.cds -2 hana -o hanaDefinitionFolder

// all targets
cds MyFirstService.cds --to yml
cds MyFirstService.cds --to yaml
cds MyFirstService.cds --to json
cds MyFirstService.cds --to cdl
cds MyFirstService.cds --to edmx
cds MyFirstService.cds --to edm
cds MyFirstService.cds --to hana
cds MyFirstService.cds --to sql
cds MyFirstService.cds --to swgr
cds MyFirstService.cds --to annos

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.