
CDS - Annotations
Annotations are an important part of CDS views, even if they don't seem to have any real function at first glance.
Table of contents
In the first two articles on Core Data Services, we had already used the first annotations without explaining them exactly or how they actually work. In this article we want to go into the function and the variety of annotations.
Basics
Annotations can be seen in Core Data Services like comments, whereby they enrich the logic and the data model of the CDS view with additional information, so-called metadata. The information can be evaluated automatically, but it also helps other developers to understand the data model more easily.
CDS annotations can be used for the following aspects, among others:
- Definition of the virtual data model
- Provision of a search help
- Linking relevant fields (amount to currency)
- CRUD operations
- Provision as an OData service
- Structure of the Fiori element
Annotation definition
Of course, if you want to use annotations, you should also know what they are and where to find them. Annotations are stored in so-called annotation definitions, which are independent objects in the system. To do this, use the "Open ABAP Development Object" function or CTRL + SHIFT + A to open any object in Eclipse and then narrow it down to objects of type DDLA, then you will get all the definitions that are available.
Let's take a look at an excerpt from the definition of SEMANTICS. We have shown the two elements "currencyCode" and "unitOfMeasure".
@Scope:[#ELEMENT]
@CompatibilityContract: {
c1: { usageAllowed: true,
allowedChanges.annotation: [ #CUSTOM ],
allowedChanges.value: [ #NONE ] },
c2: { usageAllowed: true,
allowedChanges.annotation: [ #CUSTOM ],
allowedChanges.value: [ #NONE ] } }
@API.state: [ #RELEASED_FOR_SAP_CLOUD_PLATFORM, #RELEASED_FOR_KEY_USER_APPS ]
currencyCode : Boolean default true;
@Scope:[#ELEMENT]
@CompatibilityContract: {
c1: { usageAllowed: true,
allowedChanges.annotation: [ #CUSTOM ],
allowedChanges.value: [ #NONE ] },
c2: { usageAllowed: true,
allowedChanges.annotation: [ #CUSTOM ],
allowedChanges.value: [ #NONE ] } }
@API.state: [ #RELEASED_FOR_SAP_CLOUD_PLATFORM, #RELEASED_FOR_KEY_USER_APPS ]
unitOfMeasure : Boolean default true;
In turn, other information can be derived from the annotations of the definitions. For example, whether the annotation has a certain scope and can only be used for fields (elements). Or whether the annotation works for different contracts. However, the type of field is also defined at the element and the possible characteristics are stored. Above the definition, in line 0, you also have the option of jumping to the Knowledge Transfer Document to obtain further documentation on the individual components.
Of course, you also have the option of calling up the corresponding help for the annotation in Eclipse with F2 and displaying the stored information and documentation.
Structure
In this section we want to look at how an annotation is actually structured. As you may have seen in the last article, we already listed the annotation for the virtual data model there:
@VDM.viewType: #CONSUMPTION
Basically, the annotation starts with an @ sign, followed by the annotation definition we want to use, in the above example this is VDM. In the next step, let's look at the "viewType" element to understand the content:
@CompatibilityContract:{ c1: { usageAllowed: true,
allowedChanges: { annotation: [#ANY],
value: [#ANY] }
},
c2: { usageAllowed: true,
allowedChanges: { annotation: [#ANY],
value: [#ANY] }
}
}
@API.state: [#RELEASED_FOR_KEY_USER_APPS]
@Scope:[#ENTITY]
viewType : String(30) enum { BASIC; COMPOSITE; CONSUMPTION; EXTENSION; DERIVATION_FUNCTION; TRANSACTIONAL; };
The scope is set to "Entity", so the element can only be used at the top of the view, in the header segment. The field is a 30-digit string and only certain values can be used. To do this, you can use CTRL + Space in Eclipse to call up the fill-in help and all relevant values will be suggested.
Position
In the examples shown so far, the annotation always came before the actual element to which it was assigned. But here you have the possibility to place them before or after the element, you have to comply with the appropriate syntax, plus an example for you how it could look like:
// Before element
@Semantics.currencyCode: true
waers as Currency
// After element
waers as Currency
@<Semantics.currencyCode: true
Hint: Comments in Core Data Services start with // and work differently than in ABAP. The position of the annotation should only use one of the two variants per object in order to remain consistent. However, best practice is to specify the annotation before the element.
Grouping
So far we have always given the individual annotations individually, but there is also a summary notation that is somewhat shorter and summarizes individual elements. Let's take the following example of two annotations:
@ObjectModel.dataCategory: #TEXT
@ObjectModel.representativeKey: 'CompanyCode'
In summary, we can now write the following, whereby you will certainly notice that the JSON notation is very similar:
@ObjectModel: {
dataCategory: #TEXT,
representativeKey: 'CompanyCode'
}
The grouping is done in objects {} and in lists [], as you know it from JSON.
Default values
We have already used the "currencyCode" annotation from "Semantics" above. If you look again at the definition, you will see a default value behind the element. By default, the element is set to True. This means that we don't necessarily have to specify the value here for the element to work. The following annotation is also correct:
@Semantics.currencyCode
waers as Currency
Conclusion
Annotations are an important part of Core Data Services and even have to be used in some places, for example to define the SQL view on the database. They provide a lot of additional information for the caller, whether by machine or by another developer.