This is a test message to test the length of the message box.
Login
|
ABAP RAP CDS Pattern
Erstellt von Software-Heroes

RAP - CDS Pattern

363

Wie geht eigentlich das CDS Pattern und was hat CDS-only damit zu tun? In diesem Artikel schauen wir auf die Architektur und Nutzung des Patterns.

Werbung


In diesem Artikel schauen wir uns das CDS Pattern an, wie du es implementieren und sinnvoll in deine Entwicklung einbinden kannst.

 

Einleitung

Das ABAP RESTful  Application Programming Model ist das neue Modell in ABAP, um Cloud Ready und Clean Core Anwendungen zu erstellen. Mit RAP lassen sich neben Anwendungen, auch Schnittstellen für den internen und externen Gebrauch zur Verfügung stellen. Mit den neusten Features ist RAP sehr flexibel was den Aufbau und die Nutzung angeht, weshalb wir die Anwendungen in verschiedene Pattern aufteilen möchten.

 

Aufbau

Das "CDS Pattern" wird so genannt, weil wir die CDS-only Mechanismen der Entwicklung nutzen. Wir verzichten dabei auf die klassischen Instrumente, wie Datenelemente, Domänen und DDIC Tabellen, um unser Datenmodell zu erstellen. Damit ersparen wir uns verschiedene Mappings bei der Nutzung der Daten in unserem Modell. Zur Einleitung noch die Legende für das Modell.

 

Dazu die folgenden Merkmale zur Abgrenzung:

  • Datenquelle des Models sind Table Entities (Nachfolger der DDIC Tabellen)
  • Interface Layer (CDS) wird nicht benötigt, Verhalten und Verbindungen können auf CDS Ebene modelliert werden
  • Nutzung von CDS-only (Table Entity, Simple Types, Aspects)
  • Mapping in Verhaltensdefinition nicht mehr nötig

 

 

Mit der Table Entity können wir unser Datenmodell und die Beziehungen bereits auf dieser Ebene definieren und müssen das nicht auf Interface Ebene machen. Daher können wir uns diesen Layer sparen und damit Objekte. Der Layer bleibt aber optional, wenn du vielleicht ein Mapping von Elementen machen möchtest oder andere Besonderheiten hast.

 

Beispiel

Dazu modellieren wir unsere Anwendung auf dem Datenmodell unserer Core Data Service Reihe und verwenden die Rechnung (Invoice) und die Position um ein RAP Objekt zu erstellen.

 

Datenmodell

Da wir keine klassische Tabelle haben, legen wir zwei Table Entities im System an. In diesem Fall arbeiten wir mit eingebauten Datentypen und verzichten der Einfachheit halber auf Simple Types. In der Entität müssen wir ebenfalls die neuen Datentypen für Datum und Uhrzeit verwenden, da die Alten nicht mehr unterstützt werden.

@ClientHandling.type: #CLIENT_DEPENDENT
@AbapCatalog.deliveryClass: #APPLICATION_DATA
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'CDS-P: Invoice'
define root table entity ZBS_T_CDSPatternInvoice
{
  key DocumentNumber     : abap.char(8);
      DocumentDate       : abap.datn;
      DocumentTime       : abap.timn;
      PartnerNumber      : abap.char(10);
      @Semantics.user.createdBy: true
      LocalCreatedBy     : abp_creation_user;
      @Semantics.systemDateTime.createdAt: true
      LocalCreatedAt     : abp_creation_tstmpl;
      @Semantics.user.localInstanceLastChangedBy: true
      LocalLastChangedBy : abp_locinst_lastchange_user;
      @Semantics.systemDateTime.localInstanceLastChangedAt: true
      LocalLastChangedAt : abp_locinst_lastchange_tstmpl;
      @Semantics.systemDateTime.lastChangedAt: true
      LastChangedAt      : abp_lastchange_tstmpl;

      _Position          : composition of exact one to many ZBS_T_CDSPatternPosition;
}

 

Das Mandanten-Handling passiert über die Annotation im View. Zusätzlich können wir auch direkt die Beziehung im View modellieren. Bevor wir den View aber aktivieren können, sollten wir zuvor noch die Position anlegen. Hier definieren wir auch die entsprechenden Felder, müssen allerdings noch zusätzlich die Einheit für die Menge aufnehmen, da Assoziationen an dieser Stelle nicht möglich sind.

@ClientHandling.type: #CLIENT_DEPENDENT
@AbapCatalog.deliveryClass: #APPLICATION_DATA
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'CDS-P: Position'
define table entity ZBS_T_CDSPatternPosition
{
  key DocumentNumber   : abap.char(8);
  key PositionNumber   : abap.int2;
      MaterialNumber   : abap.char(5);
      @Semantics.quantity.unitOfMeasure : 'PositionUnit'
      PositionQuantity : abap.quan(10,0);
      PositionUnit     : abap.unit(3);
      @Semantics.amount.currencyCode : 'PositionCurrency'
      PositionPrice    : abap.curr(15,2);
      PositionCurrency : abap.cuky;
      
      _Document : association to parent ZBS_T_CDSPatternInvoice on _Document.DocumentNumber = $projection.DocumentNumber;
}

 

Verhalten

Im Verhalten definieren wir noch zusätzlich Draft, verlinken die Felder und die verschiedenen Draft Actions, da wir einen OData v4 anlegen wollen. Im aktuellen Status können wir leider nur DDIC Tabellen für den Draft anlegen, dass soll Anfang 2026 sich dann ändern. Da wir das Verhalten direkt auf der Table Entity definiert haben, sparen wir uns das Mapping der Entität auf die Datenquelle.

managed implementation in class zbp_bs_cdspattern_invoice unique;
strict ( 2 );
with draft;

define behavior for ZBS_T_CDSPatternInvoice alias Invoice
draft table zbs_cp_invoice_d
lock master total etag LastChangedAt
authorization master ( instance )
etag master LocalLastChangedAt
{
  create ( authorization : global );
  update;
  delete;

  field ( readonly ) DocumentNumber;

  draft action Edit;
  draft action Activate optimized;
  draft action Discard;
  draft action Resume;
  draft determine action Prepare;

  association _Position { create; with draft; }
}

define behavior for ZBS_T_CDSPatternPosition alias Position
draft table zbs_cp_pos_d
lock dependent by _Document
authorization dependent by _Document
{
  update;
  delete;

  field ( readonly ) DocumentNumber, PositionNumber;

  association _Document { with draft; }
}

 

Abschluss

Aktuell werden Table Entities nicht in den RAP Generatoren unterstützt, daher müssen wir das komplette RAP BO per Hand aufbauen. Die restlichen Schritte, wie Projection, Service Definition und Binding können wir dann wie immer definieren. Für das Numbering weichen wir aktuell auf ein Late Numbering aus und implementieren etwas Zusatzlogik. Die weiteren Details zur Implementierung findest du im GitHub Repository im nächsten Kapitel.

 

Test

Nachdem wir dann das UI über die Metadata Extension angelegt haben, können wir die Anwendung testen. Dazu legen wir einen neuen Header an und befüllen die nötigen Informationen.

 

Nach dem Speichern wurde eine neue Nummer vergeben und die Daten auf der Datenbank abgelegt, unsere Anwendung funktioniert nun so weit, wenn auch nicht perfekt.

 

Vollständiges Beispiel

Das vollständige Beispiel findest du bei uns im GitHub Repository und über den Commit findest du alle Änderungen. Innerhalb des Repository befindet sich das Beispiel im Paket ZBS_DEMO_RAP_PATTERN_CDS. Wie bereits oben beschrieben, wirst du das Consumption Model und die Aufrufimplementierung dort nicht finden.

 

Zusammenfassung

Im Grund ist das Pattern sehr ähnlich zum Classic Pattern in der RAP Entwicklung. Dadurch, dass wir aber auf die klassischen Artefakte verzichten, können wir bereits auf Ebene der Table Entity die echten Feldnamen definieren und die Beziehungen innerhalb der Objekte modellieren. Damit können wir uns in den meisten Fällen den Interface Layer sparen und das Verhalten direkt auf die Tabelle setzen. Damit erhalten wir auch Groß- und Kleinschreibung für die Typen, Objekte und Felder und haben im Gegensatz zur Tabelle, mehr Zeichen für die Benennung.

Allerdings funktioniert das Modell noch nicht zu 100% im aktuellen Zustand. Simple Types mit ENUMs werden noch nicht auf Ebene der UI und RAP unterstützt und Draft ist zwar möglich, verwendet aber immer noch eine klassische Tabelle. Mehr der neuen Features werden in 2026 kommen, um das CDS Pattern zu unterstützen.

 

Fazit

Das CDS Pattern wird in Zukunft immer mehr das Classic Pattern ablösen und vereinfachen. Die Anzahl der Objekte wird sich reduzieren und so werden RAP Objekte leichter verständlich. Da wir auf Tabellenebene bereits Berechtigungsprüfungen umsetzen können, wird das Modell für Lesezugriffe auch etwas sicherer.


Enthaltene Themen:
RAPBTPPatternCDSCDS-only
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Dienstag und Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


RAP - Position der Buttons

Kategorie - ABAP

In diesem Artikel schauen wir uns die verschiedenen Positionen der Buttons an. Wo können wir in RAP die verschiedenen Actions platzieren und wie nutzen wir diese.

17.02.2026

RAP - Analytical Table

Kategorie - ABAP

Schauen wir uns einmal in RAP das letzten fehlende Puzzlestück zur Ablösung des ALVs an und wie wir die Analytical Table mit wenig Aufwand einrichten können.

13.02.2026

RAP - Mixed Content

Kategorie - ABAP

Wie bekommen wir eigentlich unterschiedlichen Content in die gleiche Spalte im List Report? Schauen wir uns dazu einmal ein praktisches Beispiel für unsere Sales App an.

10.02.2026

RAP - Augmentation

Kategorie - ABAP

In diesem Artikel stellen wir unser Datenmodell der RAP Anwendung um und ändern die Form wie wir mit den Texten umgehen. Dabei verwenden wir Augmentation, um unser Datenmodell trotzdem vollständig zu halten.

03.02.2026

034: Recycling-Heroes - Object and RAP Generator (Document)

Kategorie - YouTube

In dieser Episode erstellen wir unsere neue Dokumenten-App mit Hilfe von Generatoren zur Erstellung des Datenmodells und anschließend zur Erstellung des RAP Objekts.

02.02.2026