
RAP - Generator (from Scratch)
Deine Entwicklung mit RAP fühlt sich manchmal sehr langsam an? Generatoren nehmen dir die Arbeit ab, um den eigentlich Stack aufzubauen und wiederkehrende Arbeit abzunehmen.
Inhaltsverzeichnis
Es ist mittlerweile etwas her, dass wir die verschiedenen RAP-Generatoren vorgestellt haben. Damals ging es um die erste Version in ADT und eine Open Source Komponente in Fiori. In diesem Artikel schauen wir uns die nächste Generation des Generators an.
Einleitung
Der schwerste und komplexeste Teil beim Lernen des ABAP RESTful Programming Models sind die Zusammenhänge im Datenmodell und die Implementierungen der verschiedenen Funktionen. Hast du dann RAP verstanden, kann der Aufbau des eigentlichen Stacks von der Datenbank zum UI etwas anstrengend werden, da so viele Objekte und Beziehungen im System angelegt werden müssen. Hier kommen die RAP-Generatoren zum Einsatz, da sie dir die Arbeit der Anlage abnehmen können. Im Endeffekt kannst du dich dann auf die eigentliche Implementierung fokussieren.
Hinweis: Wie immer gilt, bevor du mit den RAP Generatoren loslegst, lerne die Entwicklung in RAP, um die verschiedenen Szenarien und Komponenten zu verstehen.
Vorbereitung
Bevor wir in den RAP-Generator einsteigen, benötigen wir zwei Dinge im System, die wir gleich für den Generator brauchen. Im ersten Schritt legen wir ein Paket an, am besten ein Leeres, in dem wir dann die Objekte generieren lassen können. Über das Kontextmenü generieren wir uns auf unserem RAP Paket ein neues Unterpaket.
Dem Paket geben wir einen Namen und eine Beschreibung und legen es im Anschluss im System an. Je nach System, musst du vielleicht noch einen Transport angeben.
Unter dem Paket legen wir uns einen abstrakten CDS View an, der gleich als Struktur dienen soll für den Generator und zum Test von ein paar Funktionen.
@EndUserText.label: 'Template for RAP Generator'
define abstract entity ZBS_A_GeneratorTemplate
{
@EndUserText.label: 'Position'
PositionNumber : abap.int4;
PositionText : abap.char( 200 );
@Semantics.amount.currencyCode: 'Currency'
Amount : abap.curr( 15, 2 );
@Semantics.currencyCode: true
Currency : abap.cuky( 5 );
}
Generator
In diesem Abschnitt schauen wir uns den Generator Schritt für Schritt an. Dabei gehen wir auf die Möglichkeiten und Optionen für die Generierung ein.
Start
Den Generator kannst du wie immer über das Paket starten. Im Kontextmenü findest du den Punkt "Generate ABAP Repository Objects ..." um die Auswahl der Generatoren zu starten.
Mittlerweile findest du eine große Liste von verschiedenen Generatoren im Menü. In diesem Artikel schauen wir uns den Generator im Bereich RAP an. Nach Auswahl von "OData UI Service from Scratch" starten wir den Generator.
Konfiguration
Die Möglichkeit der Einstellungen unter "Service Configuration" ist hierbei recht einfach gehalten. Du kannst den Typ des Service wählen, hier bleiben wir erst einmal bei "Transactional with Draft", da das der Standard ist. Über Prefix und Suffix können wir die erzeugten Namen weiter beeinflussen, dazu kommen wir noch einmal zum Abschluss des Artikels. Der Projektname wird überall dort verwendet, wenn es nicht um Entitäten geht, wie zum Beispiel den Service oder die Klassen.
Im nächsten Schritt definieren wir die verschiedenen Entitäten und wir diese miteinander verbunden sind. Zuerst fügen wir über den "Add" Button den Header ein, hier kannst du eigentlich nur den Alias für die Entität hinterlegen. Im nächsten Schritt definieren wir uns die Position, die unter dem Header ist. Die Kardinalität ist automatisch mit "To Many" angegeben. Über Template Name können wir Strukturen, Tabellen oder Core Data Services als Referenz mitgeben. Für die Position verwenden wir daher den angelegten CDS View.
Am Ende legen wir drei Entitäten an, einen Header, darunter Positionen und darunter noch verschiedene Notizen, die der Anwender später anlegen kann. Für die Positionen verwenden wir dabei ein Template zur Anlage.
Im nächsten Schritt legen wir die Felder auf Ebene der Entitäten an. Dazu beginnen wir auf der Header Ebene mit der Dokumenten ID, die wir später als semantischen Schlüssel verwenden wollen. Bei den Feldern kannst du mit Groß- und Kleinschreibung arbeiten, diese wird später in die Core Data Services übernommen. Die Einstellungen werden dynamisch ein- und ausgeblendet, je nach Kontext. Daher gibt es neben den Attributen für den Datentypen auch so etwas wie Schlüsselinformationen oder Referenzfelder.
Insgesamt definieren wir drei Felder auf Header Ebene für unsere Entität. Noch ein Feld für die Kundennummer und eine weitere Beschreibung der Rechnung.
Auf der Ebene der Position müssen wir nichts definieren, hier werden alle Informationen aus dem Template übernommen. Dazu zählen die Feldnamen, die Datentypen und die Beziehung von Währung zu Betrag. Allerdings mussten wir hier die Feldnamenanpassen, da der Standard nur den ersten Buchstaben groß formatiert, den Namen aus der abstrakten Entität aber ignoriert.
Auf der Ebene der Notizen benötigen wir nur ein Feld, dass wir als String definieren, um später unsere Notizen erfassen zu können. Damit sind wir mit der ersten Konfiguration durch.
Durchführung
Den Projektnamen haben wir am Anfang nicht befüllt, da dieser meist initial aus dem Namen der Root Entität befüllt wird. In den meisten Fällen beschreibt die Root Entität allerdings nicht das RAP Business Objekt. Daher ändern wir hier noch einmal den Namen.
Über den Prefix können wir noch ein Modul mitgeben, im Beispiel verwenden wir "BS_", damit wird zum Beispiel aus "ZC_G3Header" dann "ZBS_C_G3Header". Für andere Anwendungsfälle als das Modul passt es meist dann auch nicht. Über den Suffix können wir dann Objekte am Ende erweitern, dabei wird es bei jedem Objekt ans Ende angehangen. Würden wir TP definieren, dann würde aus "ZBS_C_G3Header" dann "ZBS_C_G3HeaderTP" werden.
Sind wir mit der Konfiguration dann komplett fertig, erhalten wir im nächsten Schritt eine Liste aller zu generierenden Objekte. Hier hast du die Möglichkeit auch noch einmal die Namen aller Objekte zu prüfen.
Die Generierung dauert dann einige Minuten und nach dem Abschluss erhältst du eine Information, um das Service Binding zu öffnen. Als Abschluss musst du nur noch das Service Binding über "Publish" veröffentlichen.
Nächste Schritte
Der Generator hat uns nun ca. 26 Objekte im System generiert und uns eine Menge an Arbeit gespart. Damit kannst du mit der eigentlichen Arbeit beginnen und zusätzliche Aktionen, Validierungen und Ermittlungen implementieren. Ebenfalls müssen die verschiedenen UI Elemente über die Metadata Extensions neu aufgebaut werden, da dies wahrscheinlich nicht dein Zieldesign sein wird. Wenn du lernen willst, wie du ein UI Schritt für Schritt aufbaust, schau in diesem YouTube Video von unserem Kanal vorbei. Dort erklären wir die verschiedenen Elemente und Schritte.
Joule
Der Generator wird auch durch Joule unterstützt. Ist in deinem System der AI Assistent aktiviert, dann kannst du über Joule auf Basis von Text den Generator befüllen lassen und Anpassungen vornehmen. Je nachdem wie aufwändig dein Prompt ist, kannst du damit noch Zeit sparen
Verbesserungsvorschläge
Aktuell solltest du einige Regeln beachten, wenn du mit dem Generator arbeitest.
- Die Schlüssel zwischen den Entitäten werden automatisch erzeugt und benannt. Sie basieren auf den gängigen UUIDs, es können aktuell aber keine anderen Arten von Schlüsseln definiert werden.
- Mit Suffix und Prefix können Anpassungen an Objektnamen vorgenommen werden, diese werden aber nicht 100% auf die Namenskonventionen passen.
Schauen wir uns den aktuell ausgelieferten Standard an, dann fallen uns ein paar kleinere Verbesserungen bei der Nutzung auf, hier findest du unsere Vorschläge:
- Suffix für Objekte - Position des Suffix passt nicht in allen Fällen, bei der Klasse für die Verhaltensimplementierung würde ich ZBP mit dem Suffix erwarten (ZBP_BS), dieser wird aber zwischen Z und BP eingefügt.
- Prefix für Objekte - Die Endung wird immer am Ende eingefügt, das erzeugt in einigen Fällen nicht korrekte Namen, wie zum Beispiel bei den Tabellen ZBS_TEST und ZBS_TESTD, würde ZBS_TESTTP und ZBS_TESTDTP. Damit ist die Draft Tabelle nun zum Originalobjekt abweichend. Beim Service sollte das Protokoll am Ende stehen, hier wird aber auch TP angehangen (ZBS_UI_G3INVOICE_O4TP).
- Template - Für das Template hatten wir eine abstrakte Entität genutzt, hier werden aktuell alle Zusatzinformationen ignoriert (Schreibweise der Felder, zusätzliche Labels, teilweise Datentypen INT4 -> INT8).
- Objekte - Einige Objekte sollten optional sein, wie die Object Types, das Behavior auf Consumption Ebene.
Vollständiges Beispiel
Das komplette Beispiel findest du an gewohnter Stelle bei uns im GitHub Repository. Im Paket ZBS_DEMO_RAP_GEN3 findest du die generierten Artefakte und das Template.
Fazit
Mit dem neuen RAP-Generator können nun Objekte mit mehr und verzweigten Entitäten generiert werden. Das spart bei der initialen Anlage eine Menge Zeit und Aufwand. Allerdings weichen ein paar der erzeugten Namen noch vom gewünschten Ergebnis ab und bei der Übernahme vom Template muss man noch etwas nacharbeiten. Eine Zeitersparnis ist es aber allemal für die Entwicklung.
Weitere Informationen:
YouTube - UI Modeling (Contact)