RAP (RESTful ABAP Programming) ist das moderne Programmiermodell für transaktionale Anwendungen in SAP. Es bildet die Grundlage für SAP Fiori Apps, OData Services und Cloud-Entwicklung auf SAP BTP.
Grundkonzepte
- Business Object (BO): Fachliches Objekt mit Daten und Verhalten
- CDS View: Datenmodell (siehe CDS Views)
- Behavior Definition (BDEF): Deklariert das Verhalten (CRUD, Actions, Validations)
- Behavior Implementation (BIL): Implementiert das Verhalten in ABAP
RAP-Architektur
┌─────────────────────────────────────────────┐│ Fiori UI │├─────────────────────────────────────────────┤│ OData Service │├─────────────────────────────────────────────┤│ Projection Layer (C_*) │├─────────────────────────────────────────────┤│ Business Object Layer (I_*) ││ ┌─────────────┐ ┌────────────────────┐ ││ │ CDS View │ │ Behavior │ ││ │ (Daten) │ │ Definition (BDEF) │ ││ └─────────────┘ └────────────────────┘ ││ │ ││ ┌───────────▼───────────┐ ││ │ Behavior │ ││ │ Implementation (BIL) │ ││ └───────────────────────┘ │├─────────────────────────────────────────────┤│ Datenbank │└─────────────────────────────────────────────┘Managed vs. Unmanaged Szenario
| Aspekt | Managed | Unmanaged |
|---|---|---|
| CRUD | Automatisch vom Framework | Manuell implementieren |
| Transaktionen | Framework-gesteuert | Eigene Kontrolle |
| Aufwand | Gering | Höher |
| Flexibilität | Standard-Operationen | Volle Kontrolle |
| Empfohlen für | Neue Entwicklungen | Legacy-Integration |
Beispiel: Managed Szenario
1. Datenbanktabelle
@EndUserText.label : 'Travel'@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE@AbapCatalog.tableCategory : #TRANSPARENTdefine table ztravel { key client : abap.clnt not null; key travel_id : abap.numc(8) not null; agency_id : abap.numc(6); customer_id : abap.numc(6); begin_date : abap.dats; end_date : abap.dats; total_price : abap.curr(16,2); currency_code : abap.cuky; description : abap.string(256); status : abap.char(1); created_by : abap.uname; created_at : abap.utclong; last_changed_by: abap.uname; last_changed_at: abap.utclong;}2. Interface CDS View (I_*)
@AbapCatalog.sqlViewName: 'ZITRAVELV'@AbapCatalog.compiler.compareFilter: true@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Travel - Interface View'
@Metadata.allowExtensions: true
define root view entity ZI_Travel as select from ztravel{ key travel_id as TravelId, agency_id as AgencyId, customer_id as CustomerId, begin_date as BeginDate, end_date as EndDate, @Semantics.amount.currencyCode: 'CurrencyCode' total_price as TotalPrice, @Semantics.currencyCode: true currency_code as CurrencyCode, description as Description, status as Status,
@Semantics.user.createdBy: true created_by as CreatedBy, @Semantics.systemDateTime.createdAt: true created_at as CreatedAt, @Semantics.user.lastChangedBy: true last_changed_by as LastChangedBy, @Semantics.systemDateTime.lastChangedAt: true last_changed_at as LastChangedAt}3. Behavior Definition (BDEF)
managed implementation in class zbp_i_travel unique;strict ( 2 );
define behavior for ZI_Travel alias Travelpersistent table ztravellock masterauthorization master ( instance )etag master LastChangedAt{ // Standard-Operationen create; update; delete;
// Feldmapping für Datenbank field ( readonly ) TravelId; field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
// Automatische Nummernvergabe field ( numbering : managed ) TravelId;
// Actions action ( features : instance ) acceptTravel result [1] $self; action ( features : instance ) rejectTravel result [1] $self;
// Validations validation validateDates on save { field BeginDate, EndDate; } validation validateCustomer on save { field CustomerId; }
// Determinations determination setStatusNew on modify { create; }}4. Behavior Implementation (BIL)
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS: get_instance_features FOR INSTANCE FEATURES IMPORTING keys REQUEST requested_features FOR Travel RESULT result,
acceptTravel FOR MODIFY IMPORTING keys FOR ACTION Travel~acceptTravel RESULT result,
rejectTravel FOR MODIFY IMPORTING keys FOR ACTION Travel~rejectTravel RESULT result,
validateDates FOR VALIDATE ON SAVE IMPORTING keys FOR Travel~validateDates,
validateCustomer FOR VALIDATE ON SAVE IMPORTING keys FOR Travel~validateCustomer,
setStatusNew FOR DETERMINE ON MODIFY IMPORTING keys FOR Travel~setStatusNew.ENDCLASS.
CLASS lhc_travel IMPLEMENTATION.
METHOD get_instance_features. " Lese aktuelle Daten READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel) FAILED failed.
" Feature-Control basierend auf Status result = VALUE #( FOR ls_travel IN lt_travel ( %tky = ls_travel-%tky %features-%action-acceptTravel = COND #( WHEN ls_travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) %features-%action-rejectTravel = COND #( WHEN ls_travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ) ). ENDMETHOD.
METHOD acceptTravel. " Status auf 'Accepted' setzen MODIFY ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel UPDATE FIELDS ( Status ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky Status = 'A' ) ) FAILED failed REPORTED reported.
" Ergebnis zurückgeben READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel ALL FIELDS WITH CORRESPONDING #( keys ) RESULT result. ENDMETHOD.
METHOD rejectTravel. MODIFY ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel UPDATE FIELDS ( Status ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky Status = 'X' ) ) FAILED failed REPORTED reported.
READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel ALL FIELDS WITH CORRESPONDING #( keys ) RESULT result. ENDMETHOD.
METHOD validateDates. " Daten lesen READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( BeginDate EndDate ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
LOOP AT lt_travel INTO DATA(ls_travel). " Enddatum muss nach Beginn liegen IF ls_travel-EndDate < ls_travel-BeginDate. APPEND VALUE #( %tky = ls_travel-%tky %element-EndDate = if_abap_behv=>mk-on ) TO failed-travel.
APPEND VALUE #( %tky = ls_travel-%tky %element-EndDate = if_abap_behv=>mk-on %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Enddatum muss nach Beginndatum liegen' ) ) TO reported-travel. ENDIF.
" Beginn darf nicht in der Vergangenheit liegen IF ls_travel-BeginDate < cl_abap_context_info=>get_system_date( ). APPEND VALUE #( %tky = ls_travel-%tky %element-BeginDate = if_abap_behv=>mk-on ) TO failed-travel.
APPEND VALUE #( %tky = ls_travel-%tky %element-BeginDate = if_abap_behv=>mk-on %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Beginndatum darf nicht in der Vergangenheit liegen' ) ) TO reported-travel. ENDIF. ENDLOOP. ENDMETHOD.
METHOD validateCustomer. READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( CustomerId ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
" Kunden prüfen LOOP AT lt_travel INTO DATA(ls_travel). IF ls_travel-CustomerId IS INITIAL. APPEND VALUE #( %tky = ls_travel-%tky %element-CustomerId = if_abap_behv=>mk-on ) TO failed-travel.
APPEND VALUE #( %tky = ls_travel-%tky %element-CustomerId = if_abap_behv=>mk-on %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Kunde ist erforderlich' ) ) TO reported-travel. ENDIF. ENDLOOP. ENDMETHOD.
METHOD setStatusNew. " Bei Neuanlage Status auf 'Open' setzen READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
MODIFY ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel UPDATE FIELDS ( Status ) WITH VALUE #( FOR ls_travel IN lt_travel WHERE ( Status IS INITIAL ) ( %tky = ls_travel-%tky Status = 'O' ) ) REPORTED reported. ENDMETHOD.
ENDCLASS.5. Projection View (C_*)
@EndUserText.label: 'Travel - Projection View'@AccessControl.authorizationCheck: #CHECK@Metadata.allowExtensions: true@Search.searchable: true
define root view entity ZC_Travel provider contract transactional_query as projection on ZI_Travel{ key TravelId,
@Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.8 AgencyId,
@Search.defaultSearchElement: true CustomerId,
BeginDate, EndDate, TotalPrice, CurrencyCode,
@Search.defaultSearchElement: true Description,
@ObjectModel.text.element: ['StatusText'] Status, _StatusText.Text as StatusText : localized,
CreatedBy, CreatedAt, LastChangedBy, LastChangedAt}6. Projection Behavior Definition
projection;strict ( 2 );
define behavior for ZC_Travel alias Travel{ use create; use update; use delete;
use action acceptTravel; use action rejectTravel;}7. Service Definition
@EndUserText.label: 'Travel Service Definition'define service ZUI_TRAVEL_O4 { expose ZC_Travel as Travel;}8. Service Binding
- Name: ZUI_TRAVEL_O4- Binding Type: OData V4 - UI- Service Definition: ZUI_TRAVEL_O4EML – Entity Manipulation Language
" === READ ENTITIES ===READ ENTITIES OF zi_travel ENTITY Travel FIELDS ( TravelId AgencyId Status ) WITH VALUE #( ( TravelId = '00000001' ) ) RESULT DATA(lt_travel) FAILED DATA(failed) REPORTED DATA(reported).
" === MODIFY ENTITIES - Create ===MODIFY ENTITIES OF zi_travel ENTITY Travel CREATE FIELDS ( AgencyId CustomerId BeginDate EndDate ) WITH VALUE #( ( %cid = 'CID_1' AgencyId = '000001' CustomerId = '000010' BeginDate = cl_abap_context_info=>get_system_date( ) EndDate = cl_abap_context_info=>get_system_date( ) + 7 ) ) MAPPED DATA(mapped) FAILED failed REPORTED reported.
" === MODIFY ENTITIES - Update ===MODIFY ENTITIES OF zi_travel ENTITY Travel UPDATE FIELDS ( Status Description ) WITH VALUE #( ( TravelId = '00000001' Status = 'A' Description = 'Aktualisiert' ) ) FAILED failed REPORTED reported.
" === MODIFY ENTITIES - Delete ===MODIFY ENTITIES OF zi_travel ENTITY Travel DELETE FROM VALUE #( ( TravelId = '00000001' ) ) FAILED failed REPORTED reported.
" === MODIFY ENTITIES - Execute Action ===MODIFY ENTITIES OF zi_travel ENTITY Travel EXECUTE acceptTravel FROM VALUE #( ( TravelId = '00000001' ) ) FAILED failed REPORTED reported.
" === COMMIT ENTITIES ===COMMIT ENTITIES RESPONSE OF zi_travel FAILED DATA(commit_failed) REPORTED DATA(commit_reported).Behavior-Elemente
Actions
" Instanz-Action (auf eine Zeile)action acceptTravel result [1] $self;
" Statische Action (ohne Instanz)static action createFromTemplate result [1] $self;
" Factory Action (erstellt neue Instanz)factory action copyTravel [1];
" Mit Parameternaction setStatus parameter ZA_StatusParameter result [1] $self;Validations
" Bei Savevalidation validateDates on save { field BeginDate, EndDate; }
" Bei Modify (sofortige Prüfung)validation validatePrice on modify { field TotalPrice; }
" Draft-Validationsdraft validation validateConsistency on save;Determinations
" Bei Createdetermination setDefaults on modify { create; }
" Bei Feldänderungdetermination calculateTotal on modify { field Quantity, Price; }
" Bei Savedetermination generateNumber on save { create; }Feature Control
" Globale Featuresfield ( readonly ) TravelId;field ( mandatory ) CustomerId;field ( readonly : update ) AgencyId;
" Instanz-Features (dynamisch)action ( features : instance ) acceptTravel;Draft Handling
managed implementation in class zbp_i_travel unique;strict ( 2 );with draft;
define behavior for ZI_Travel alias Travelpersistent table ztraveldraft table zdraft_travellock mastertotal etag LastChangedAtauthorization master ( instance )etag master LastChangedAt{ create; update; delete;
// Draft-Actions (automatisch verfügbar) draft action Edit; draft action Activate optimized; draft action Discard; draft action Resume; draft determine action Prepare;}Wichtige Klassen
| Klasse | Beschreibung |
|---|---|
cl_abap_behavior_handler | Basisklasse für Behavior Implementation |
cl_abap_context_info | System-Kontext (Datum, User) |
if_abap_behv | Konstanten (fc-o-enabled, mk-on) |
if_abap_behv_message | Message-Severity |
Wichtige Hinweise / Best Practice
- Managed Szenario für neue Entwicklungen – Framework übernimmt CRUD.
- Interface Views (I_*) für Datenmodell, Projection Views (C_*) für UI/API.
- EML (Entity Manipulation Language) für programmatischen BO-Zugriff.
- Validations für Geschäftsregeln, Determinations für automatische Werte.
- Actions für Geschäftsoperationen jenseits von CRUD.
- Feature Control für dynamische Feld-/Aktionsverfügbarkeit.
- Draft für Zwischenspeicherung bei komplexen Eingaben.
- Nutzen Sie
IN LOCAL MODEfür Zugriff ohne Berechtigungsprüfung. FAILEDundREPORTEDfür Fehlerbehandlung und Nachrichten.- Strict Mode (
strict ( 2 )) für Best-Practice-Validierung. - Kombinieren Sie mit CDS Views für das Datenmodell.