Skip to Content
Technical Articles

SAP Cloud Platform Backend service: Tutorial [11]: CDS : magic: key: generation

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

As you know, Backend service allows to create APIs based on a given model.
The type of such model can be CDS, edmx or openAPI.
You might have wondered why we’re focusing on CDS in our tutorial series.
The reason is that CDS is powerful.

In previous blog posts we’ve already learned some of the CDS magic like
Managed associations
and Implicit redirect of associations at runtime.

In this blog we’re going to learn one more magic feature:
The automatic key generation.

Cool, I was wanting this feature since long time
Then you can directly jump to the solution.

 

The background

In our previous examples, when creating sample data, we were using key fields (like “customerID”) with numbers as possible data type (Integer)
So when creating the sample data, we had to make sure to always use a unique number, which hasn’t been used before.
That’s of course not very convenient.
So for what do we have software?
Yes, what we want is to have somebody – or something – which finds an appropriate unused number for us.
Or which generates a unique identifier for us.

 

The solution

And here comes the superstar:

CDS has the solution,
it is the

U U I D

data type.

See the SAP help portal for the documentation of CDS types.

In many cases, when modelling your data model, you can specify the data type of a key property as UUID

Example:

service PetService {

    entity Pets {
        key id: UUID;
        name : String;
        species : String;
    }
}

 

The benefit

The benefit is:
When creating entries for such properties, you don’t need to specify anything for the key.
It is always generated.

Testing it
Create an API for the above example, the you can create your pets like this:

{
“name”: “kitty”,
“species”: “frog”
}

As you can see, the key field is not even specified in the payload.
And even if you would specify any value, it would be overridden.

When creating entries, you can even hit the “execute” button multiple times.
Wow, I always wanted to do that
That’s not a problem, because the key field is always different.
But then the name of the frogs will be the same…
What’s the problem with owning many frogs with the same name?
True, they anyways don’t obey…

Example collection after creation:

The disadvantage

The UUID was presented as super-hero, how can it have disadvantages?

We can see the disadvantage in the screenshot above.
The colour?

The generated value of a UUID property is 36 characters long.
If the web application intends to display the value of that property, then such value is not very suitable, too long and not human readable.
As such, the UUID data type should be used rather if the key properties are hidden from the end-user and only processed by machines.

How does it work?
When a new entry is created vie HTTP POST, the Java (e.g.) implementation of the OData service takes care of generating the value.
Both aspects, the generation-step and the long value might cause performance drawbacks.
But only in case of big models and huge amount of data.
Since the SAP Cloud Platform Backend service targets easy creation of simple applications, the performance drawback shouldn’t be a big problem.

The navigation

And what if I have associations between entities which have key fields with generated UUID values?

Don’t worry, there’s no problem with it.

You can try this example:

service ProductService {

    entity Products {
        key id: UUID;
        name : String;
        linkToCategory : Association to Categories;
    }

    entity Categories{
        key id : UUID;
        name : String;
    }
}

Afterwards follow the navigation link, just as you’re used to:

…/SERVICE/Products(1d40bf5e-1c24-4365-af45-38d069b083f2)/linkToCategory

The result is as expected:

The OData protocol version 4 and 2

We need to spend a few words about OData, otherwise you might have this problem…. and what would you do without help in a tutorial…?
Yes, please, I always have every type of problems…
Correct, just like me.

When creating an API, the endpoint is automatically activated for OData protocol V4
For several reasons, it makes sense to stick to the newer protocol version.

We click on the V4 link and open the metadata document:

We can see that the CDS data type UUID is translated into Edm.Guid in OData V4

Fine.

Now we open the “Pets” collection:

https://…/PETSERVICE/Pets

Then we want to call the URL of one single entry.

How do I compose a READ URL in V4?

This is done just as you’re used to: append the key in brackets.

In our example, when reading a single resource of the service, the URL is composed as follows:

https://…/PETSERVICE/Pets(2bc690f8-4cef-4c22-8213-20940e303650)

As you can see, the guid is written between the brackets, without single quotes
See the Links section for links to the OData specification.

How do I compose a READ URL in V2?

With one click we can activate the OData V2 endpoint.

Then try to do the same single READ:

…/odatav2/DEFAULT/SERVICE/Pets(2bc690f8-4cef-4c22-8213-20940e303650)

This time we get an error:

Unknown literal: ‘[2bc690f8-4cef-4c22-8213-20940e303650]’.

Let’s not try to understand the error message … … let’s just assume the URL is incorrect.
How do I learn how to compose a URL
Well, just read my blogs
No marketing please
For more info, you can always refer to the OData specification:
Go to the overview page: https://www.odata.org/documentation/odata-version-2-0/overview/  and scroll down to
“6. Primitive Data Types”
Quote:
“summaries the set of primitive types supported as well as how each MUST be represented when used in an OData URI”

There’s a table where you get info about how the Edm.Guid is represented:
Also an example is given:

guid’12345678-aaaa-bbbb-cccc-ddddeeeeffff’

Note:
Composing the READ URL containing GUID is different in OData V2 and V4
In V4 you just put the guid valud in brackets
In V2 you have to write the term “guid” and the value with single quotes

Can we have a real concrete example?
OK, according to our example, the URL has to be composed like this:

…/odatav2/DEFAULT/SERVICE/Pets(guid’2bc690f8-4cef-4c22-8213-20940e303650′)

Note:
About the URL examples which I’m giving:
you might have observed that I’ve removed the ;v=1
This can be done as long as there’s only one version of your API available

Summary

We have learned that in CDS we can assign the built-in data type UUID to a key property.
At runtime, the value for such property will be generated by the framework.
Means that at runtime, when creating entries, that property can be omitted from the request payload.

Links

OData V4 specification
URL conventions entry page.
URL conventions: Addressing entities
URL conventions: Addressing single entity with canonical URL
URL conventions: Example for guid as primitive literal
The ABNF rule for constructing the key with guid as primitive literal, at “7. Literal Data Values”

OData V2 specification
Overview page then scroll down to “6. Primitive Data Types”

SAP Help Portal
CDS types
Best practices for using UUID

Tutorials
Entry page for series of tutorials
First time creating an API with Backend service

 

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