CDS - Annotationen
Annotationen sind ein wichtiger Bestandteil von CDS Views, auch wenn sie im ersten Moment so scheint als hätten sie keine echte Funktion.
Inhaltsverzeichnis
In den ersten beiden Artikeln zum Thema Core Data Services hatten wir bereits erste Annotationen verwendet, ohne diese genau zu erklären oder wie sie eigentlich funktionieren. In diesem Artikel wollen wir auf die Funktion und die Vielfalt an Annotationen eingehen.
Grundlage
Annotationen sind im Core Data Services wie Kommentare zu sehen, wobei sie die Logik und das Datenmodell des CDS Views mit Zusatzinformationen, sogenannten Metadaten, anreichern. Die Informationen können maschinell ausgewertet werden, dienen aber auch anderen Entwicklern dazu das Datenmodell einfacher zu verstehen.
CDS-Annotationen können unter anderem für folgende Aspekte verwendet werden:
- Definition des Virtuellen Datenmodells
- Bereitstellung einer Suchhilfe
- Verknüpfung relevanter Felder (Betrag zu Währung)
- CRUD Operationen
- Bereitstellung als OData Service
- Aufbau des Fiori Elements
Annotationsdefinition
Wenn du Annotationen verwenden möchtest, solltest du natürlich auch wissen, welche es gibt und wo man sie findet. Annotationen werden in sogenannten Annotationsdefinitionen abgelegt, hierbei handelt es sich um eigenständige Objekte im System. Dazu über die Funktion "Open ABAP Development Object" oder STRG + SHIFT + A gehen, um ein beliebiges Objekt in Eclipse zu öffnen und dann auf Objekte des Typs DDLA eingrenzen, dann erhält man alle Definitionen die verfügbar sind.
Schauen wir uns dazu einmal einen Auszug aus der Definition der SEMANTICS an. Dabei haben wir die beiden Elemente "currencyCode" und "unitOfMeasure" dargestellt.
@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;
Aus den Annotationen der Definitionen kann man widerrum andere Informationen ableiten. Zum Beispiel ob die Annotation einen gewissen Scope hat und nur bei Feldern (Elements) eingesetz werden kann. Oder ob die Annotation bei verschiedenen Freigaben (Contract) funktioniert. Am Element wird aber auch der Typ des Feldes definiert und die möglichen Ausprägungen hinterlegt. Über der Definition, in Zeile 0, hast du auch noch die Möglichkeit ins Knowledge Transfer Document abzuspringen, um weitere Dokumentationen zu den einzelnen Bestandteilen zu erhalten.
Weiterhin hast du natürlich auch die Möglichkeit mit F2 die entsprechende Hilfe für die Annotation in Eclipse aufzurufen und dir die hinterlegten Informationen und Dokumentation anzuzeigen.
Aufbau
Wie ist eine Annotation nun eigentlich aufgebaut, dass wollen wir uns in diesem Abschnitt anschauen. Wie du vielleicht im letzten Artikel gesehen hattest, hatten wir dort bereits die Annotation für das virtuelle Datenmodell aufgeführt:
@VDM.viewType: #CONSUMPTION
Grundsätzlich beginnt die Annotation mit einem @ Zeichen, gefolgt von der Annotationsdefinition die wir verwenden wollen, im oberen Beispiel ist das VDM. Schauen wir uns im nächsten Schritt das Element "viewType" an, um den Inhalt zu verstehen:
@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; };
Der Scope steht auf "Entity", damit kann das Element nur an oberster Stelle im View verwendet werden, im Kopfsegment. Bei dem Feld handelt es sich um einen 30 Stellen langen String und es können nur bestimmte Werte verwendet werden. Hierzu kannst du in Eclipse über STRG + Leertaste die Ausfüllhilfe aufrufen und bekommst alle relevanten Werte vorgeschlagen.
Position
In den bisher gezeigten Beispielen stand die Annotation immer vor dem eigentlichen Element dem sie zugeordnet war. Hier hat man aber die Möglichkeit diese vor oder nach dem Element zu platzieren, dazu muss man die entsprechende Syntax einhalten, dazu ein Beispiel für dich wie es aussehen könnte:
// Before element
@Semantics.currencyCode: true
waers as Currency
// After element
waers as Currency
@<Semantics.currencyCode: true
Hinweis: Kommentare in Core Data Services beginnen mit // und funktionieren anders als in ABAP. Die Position der Annotation sollte pro Objekt nur eine von beiden Varianten verwenden, um Konsistent zu bleiben. Best Practice ist allerdings die Annotation vor dem Element anzugeben.
Gruppierung
Bisher haben wir die einzelnen Annotationen immer einzeln angegeben, hierfür gibt es aber auch eine zusammenfassende Schreibweise die etwas kürzer ist und einzelne Element zusammenfasst. Nehmen wir dazu das folgende Beispiel von zwei Annotationen:
@ObjectModel.dataCategory: #TEXT
@ObjectModel.representativeKey: 'CompanyCode'
Zusammenfassend können wir nun das Folgende schreiben, wobei dir sicherlich auffällt, dass die Schreibweise JSON sehr stark ähnlich ist:
@ObjectModel: {
dataCategory: #TEXT,
representativeKey: 'CompanyCode'
}
Die Gruppierung erfolgt in Objekten {} und in Listen [], so wie du es von JSON kennst.
Defaultwerte
Bereits oben haben wir aus "Semantics" die Annotation "currencyCode" verwendet. Wenn du dir noch einmal die Definition anschaust, wirst du einen Defaultwert hinter dem Element sehen. Standardmäßig steht das Element auf True. Dies heißt, dass wir hier nicht unbedingt den Wert angeben müssen, damit das Element funktioniert. Die folgende Annotation ist ebenso korrekt:
@Semantics.currencyCode
waers as Currency
Fazit
Annotationen sind ein wichtiger Bestandteil von Core Data Services und müssen an einigen Stellen sogar verwendet werden, um zum Beispiel den SQL-View auf der Datenbank zu definieren. Sie liefern viele zusätzliche Informationen für den Aufrufer, egal ob maschinell oder durch einen anderen Entwickler.