Das klassische RAP erfordert mehrere Schichten: Datenbanktabelle, Interface CDS View, Projection View, Behavior Definition und Service Definition. Das RAP CDS Pattern (auch CDS-only Pattern genannt) vereinfacht diese Architektur erheblich - mit Table Entities als zentralem Element.
Das Problem: Zu viele Objekte
Für eine einfache CRUD-Anwendung benötigt der klassische RAP-Stack:
1. Datenbanktabelle (ZFLIGHT_BOOK)2. Interface CDS View (ZI_FlightBooking)3. Projection CDS View (ZC_FlightBooking)4. Behavior Definition (ZI_FlightBooking)5. Behavior Implementation (ZBP_I_FLIGHTBOOKING)6. Service Definition (ZUI_FLIGHTBOOKING)7. Service Binding (ZUI_FLIGHTBOOKING_O4)Für ein einfaches Datenobjekt sind das sieben Entwicklungsobjekte - viel Overhead für CRUD-Operationen.
Die Lösung: Table Entities
Mit Table Entities (eingeführt mit ABAP Cloud 2024) wird die Tabelle selbst zum Entity:
1. Table Entity (ZI_FlightBooking) - Tabelle + View in einem2. Behavior Definition (ZI_FlightBooking)3. Service Definition (ZUI_FLIGHTBOOKING)4. Service Binding (ZUI_FLIGHTBOOKING_O4)Nur noch vier Objekte - und oft ist keine Behavior Implementation nötig.
Klassisch vs. CDS Pattern
| Aspekt | Klassischer RAP Stack | CDS Pattern |
|---|---|---|
| Objekte | 5-7 | 3-4 |
| Tabellendefinition | Separates DDL | In Table Entity |
| Interface View | Eigene CDS View | Table Entity selbst |
| Projection View | Erforderlich | Optional |
| Flexibilität | Maximal | Standard-CRUD |
| Berechnete Felder | Ja | Nein |
| Aliase | Frei wählbar | Identisch mit Spalte |
| Empfohlen für | Komplexe BOs | Einfache CRUD |
Vollständiges Beispiel: Flugbuchung
Schritt 1: Table Entity definieren
Das Table Entity kombiniert Tabellendefinition und CDS View:
@EndUserText.label: 'Flugbuchung'@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE@AbapCatalog.tableCategory: #TRANSPARENT@AbapCatalog.deliveryClass: #A@AbapCatalog.dataMaintenance: #RESTRICTED
define table entity zi_flightbooking { key client : abap.clnt not null; key booking_id : abap.numc(10) not null;
// Geschäftsdaten flight_date : abap.dats; carrier_id : abap.char(3); connection_id : abap.numc(4); customer_id : abap.numc(10);
// Buchungsdetails @Semantics.amount.currencyCode: 'zi_flightbooking.currency_code' flight_price : abap.curr(15,2); currency_code : abap.cuky; booking_status : abap.char(1);
// Administrative Felder (wichtig für RAP!) @Semantics.user.createdBy: true created_by : abap.uname; @Semantics.systemDateTime.createdAt: true created_at : abap.utclong; @Semantics.user.lastChangedBy: true last_changed_by : abap.uname; @Semantics.systemDateTime.lastChangedAt: true last_changed_at : abap.utclong; @Semantics.systemDateTime.localInstanceLastChangedAt: true local_last_changed : abap.utclong;}Wichtig: Die Semantics-Annotationen für administrative Felder ermöglichen automatisches Befüllen durch das RAP-Framework.
Schritt 2: Behavior Definition
Die Behavior Definition referenziert direkt das Table Entity:
managed implementation in class zbp_i_flightbooking unique;strict ( 2 );
define behavior for zi_flightbooking alias FlightBookinglock masterauthorization master ( instance )etag master local_last_changed{ // Standard CRUD - Framework übernimmt alles create; update; delete;
// Felder schreibgeschützt field ( readonly ) booking_id; field ( readonly ) created_by, created_at, last_changed_by, last_changed_at; field ( readonly : update ) carrier_id, connection_id, flight_date;
// Automatische Nummernvergabe field ( numbering : managed ) booking_id;
// Einfache Actions action confirmBooking result [1] $self; action cancelBooking result [1] $self;
// Validierung validation validateFlightDate on save { field flight_date; } validation validateCustomer on save { field customer_id; }
// Determination für Status determination setInitialStatus on modify { create; }
// Mapping - identisch da Table Entity mapping for zi_flightbooking corresponding;}Schritt 3: Service Definition
@EndUserText.label: 'Flugbuchung Service'define service ZUI_FLIGHTBOOKING { expose zi_flightbooking as FlightBooking;}Schritt 4: Service Binding
Name: ZUI_FLIGHTBOOKING_O4Service: ZUI_FLIGHTBOOKINGBinding Type: OData V4 - UINach dem Aktivieren und Veröffentlichen steht die Fiori Elements App bereit.
Behavior Implementation (optional)
Für Actions und Validierungen benötigen Sie eine Implementierungsklasse:
CLASS zbp_i_flightbooking DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zi_flightbooking.ENDCLASS.
CLASS zbp_i_flightbooking IMPLEMENTATION.ENDCLASS.
CLASS lhc_flightbooking DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS: confirmBooking FOR MODIFY IMPORTING keys FOR ACTION FlightBooking~confirmBooking RESULT result,
cancelBooking FOR MODIFY IMPORTING keys FOR ACTION FlightBooking~cancelBooking RESULT result,
validateFlightDate FOR VALIDATE ON SAVE IMPORTING keys FOR FlightBooking~validateFlightDate,
validateCustomer FOR VALIDATE ON SAVE IMPORTING keys FOR FlightBooking~validateCustomer,
setInitialStatus FOR DETERMINE ON MODIFY IMPORTING keys FOR FlightBooking~setInitialStatus.ENDCLASS.
CLASS lhc_flightbooking IMPLEMENTATION. METHOD confirmBooking. " Status auf 'Bestätigt' setzen MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky booking_status = 'C' ) ).
" Ergebnis zurückgeben READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
result = VALUE #( FOR booking IN bookings ( %tky = booking-%tky %param = booking ) ). ENDMETHOD.
METHOD cancelBooking. MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky booking_status = 'X' ) ).
READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
result = VALUE #( FOR booking IN bookings ( %tky = booking-%tky %param = booking ) ). ENDMETHOD.
METHOD validateFlightDate. READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking FIELDS ( flight_date ) WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT bookings INTO DATA(booking). IF booking-flight_date < cl_abap_context_info=>get_system_date( ). APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Flugdatum muss in der Zukunft liegen' ) %element-flight_date = if_abap_behv=>mk-on ) TO reported-flightbooking.
APPEND VALUE #( %tky = booking-%tky ) TO failed-flightbooking. ENDIF. ENDLOOP. ENDMETHOD.
METHOD validateCustomer. " Kundenvalidierung implementieren READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking FIELDS ( customer_id ) WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT bookings INTO DATA(booking). IF booking-customer_id IS INITIAL. APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Kunde muss angegeben werden' ) %element-customer_id = if_abap_behv=>mk-on ) TO reported-flightbooking.
APPEND VALUE #( %tky = booking-%tky ) TO failed-flightbooking. ENDIF. ENDLOOP. ENDMETHOD.
METHOD setInitialStatus. READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking FIELDS ( booking_status ) WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status ) WITH VALUE #( FOR booking IN bookings WHERE ( booking_status IS INITIAL ) ( %tky = booking-%tky booking_status = 'O' ) ). ENDMETHOD.ENDCLASS.Aktuelle Limitierungen
Das CDS Pattern ist leistungsfähig, hat aber Einschränkungen (Stand Februar 2026):
ENUMs nicht direkt unterstützt
" ❌ Funktioniert NICHT in Table Entitiesbooking_status : zbooking_status_enum;
" ✅ Workaround: CHAR-Feld mit Value Helpbooking_status : abap.char(1);Die Enum-Werte müssen über eine separate Value Help oder CDS Annotation bereitgestellt werden.
Draft-Handling eingeschränkt
" ❌ Draft erfordert klassischen RAP Stack mit Projection Viewwith draft;
" ✅ Im CDS Pattern: Nur ohne Draft möglich" Table Entity unterstützt kein draft tableFür Draft-Funktionalität benötigen Sie weiterhin den klassischen RAP-Aufbau mit Interface View und Projection View.
Keine berechneten Felder
" ❌ In Table Entity NICHT möglichcalculated_field : abap.char(10) = concat(carrier_id, connection_id);
" ✅ Klassische CDS Viewdefine view entity ZI_FlightBooking as select from zflight_book { key booking_id, concat(carrier_id, connection_id) as FlightNumber}Keine Assoziationen zu anderen Table Entities
" ❌ Table Entity kann keine Assoziationen definierenassociation [1..1] to zi_customer as _Customer;
" ✅ Workaround: Separate CDS View für AssoziationenWann welches Pattern?
CDS Pattern empfohlen
- Einfache CRUD-Anwendungen ohne komplexe Beziehungen
- Stammdatenpflege (Kunden, Produkte, Konfigurationen)
- Schnelle Prototypen und MVPs
- Anwendungen ohne Draft-Anforderung
- Standalone Entities ohne Hierarchien
Klassischer RAP Stack empfohlen
- Komplexe Business Objects mit Parent-Child-Hierarchien
- Draft-Handling erforderlich
- Berechnete Felder in der View nötig
- Feldaliase für bessere Lesbarkeit
- Assoziationen zwischen Entities
- Unterschiedliche Projections für verschiedene Apps
Migration: Von CDS Pattern zu klassischem Stack
Wenn Anforderungen wachsen, können Sie migrieren:
" 1. Table Entity bleibt als Datenbanktabelle erhalten" (Umbenennen zu ztable_flightbooking)
" 2. Neue Interface CDS View erstellendefine root view entity ZI_FlightBooking as select from ztable_flightbooking{ key booking_id as BookingId, " ... weitere Felder mit Aliasen}
" 3. Behavior Definition anpassendefine behavior for ZI_FlightBookingpersistent table ztable_flightbooking" ...Fazit
Das RAP CDS Pattern reduziert den Entwicklungsaufwand für einfache RAP-Anwendungen erheblich:
| Kriterium | CDS Pattern | Klassisch |
|---|---|---|
| Entwicklungsobjekte | 3-4 | 5-7 |
| Einarbeitungszeit | Kürzer | Länger |
| Flexibilität | Standard | Maximum |
| Draft Support | Nein | Ja |
| Assoziationen | Eingeschränkt | Voll |
Für Neueinsteiger und einfache CRUD-Anwendungen ist das CDS Pattern der schnellste Weg zur funktionierenden Fiori App. Bei wachsenden Anforderungen lässt sich auf den klassischen Stack migrieren.
Weiterführende Artikel: RAP Grundlagen für das klassische Pattern, Tabellen in ABAP Cloud für Tabellendefinitionen, RAP Managed vs Unmanaged für die Architekturentscheidung und CDS Views für komplexe Datenmodelle.