RAP (RESTful ABAP Programming) is the modern programming model for transactional applications in SAP. It forms the foundation for SAP Fiori Apps, OData Services, and cloud development on SAP BTP.
Core Concepts
- Business Object (BO): Business object with data and behavior
- CDS View: Data model (see CDS Views)
- Behavior Definition (BDEF): Declares the behavior (CRUD, Actions, Validations)
- Behavior Implementation (BIL): Implements the behavior in ABAP
RAP Architecture
┌─────────────────────────────────────────────┐│ Fiori UI │├─────────────────────────────────────────────┤│ OData Service │├─────────────────────────────────────────────┤│ Projection Layer (C_*) │├─────────────────────────────────────────────┤│ Business Object Layer (I_*) ││ ┌─────────────┐ ┌────────────────────┐ ││ │ CDS View │ │ Behavior │ ││ │ (Data) │ │ Definition (BDEF) │ ││ └─────────────┘ └────────────────────┘ ││ │ ││ ┌───────────▼───────────┐ ││ │ Behavior │ ││ │ Implementation (BIL) │ ││ └───────────────────────┘ │├─────────────────────────────────────────────┤│ Database │└─────────────────────────────────────────────┘Managed vs. Unmanaged Scenario
| Aspect | Managed | Unmanaged |
|---|---|---|
| CRUD | Automatic by framework | Manually implemented |
| Transactions | Framework-controlled | Full control |
| Effort | Low | Higher |
| Flexibility | Standard operations | Full control |
| Recommended for | New developments | Legacy integration |
Example: Managed Scenario
1. Database Table
@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 operations create; update; delete;
// Field mapping for database field ( readonly ) TravelId; field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
// Automatic number assignment 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. " Read current data READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel) FAILED failed.
" Feature control based on 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. " Set status to 'Accepted' 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.
" Return result 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. " Read data 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). " End date must be after begin date 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 = 'End date must be after begin date' ) ) TO reported-travel. ENDIF.
" Begin date must not be in the past 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 = 'Begin date must not be in the past' ) ) 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).
" Validate customer 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 = 'Customer is required' ) ) TO reported-travel. ENDIF. ENDLOOP. ENDMETHOD.
METHOD setStatusNew. " Set status to 'Open' on create 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 = 'Updated' ) ) 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 Elements
Actions
" Instance action (on a single row)action acceptTravel result [1] $self;
" Static action (without instance)static action createFromTemplate result [1] $self;
" Factory action (creates new instance)factory action copyTravel [1];
" With parametersaction setStatus parameter ZA_StatusParameter result [1] $self;Validations
" On savevalidation validateDates on save { field BeginDate, EndDate; }
" On modify (immediate validation)validation validatePrice on modify { field TotalPrice; }
" Draft validationsdraft validation validateConsistency on save;Determinations
" On createdetermination setDefaults on modify { create; }
" On field changedetermination calculateTotal on modify { field Quantity, Price; }
" On savedetermination generateNumber on save { create; }Feature Control
" Global featuresfield ( readonly ) TravelId;field ( mandatory ) CustomerId;field ( readonly : update ) AgencyId;
" Instance features (dynamic)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 (automatically available) draft action Edit; draft action Activate optimized; draft action Discard; draft action Resume; draft determine action Prepare;}Important Classes
| Class | Description |
|---|---|
cl_abap_behavior_handler | Base class for Behavior Implementation |
cl_abap_context_info | System context (date, user) |
if_abap_behv | Constants (fc-o-enabled, mk-on) |
if_abap_behv_message | Message severity |
Important Notes / Best Practices
- Managed scenario for new developments – framework handles CRUD.
- Interface Views (I_*) for data model, Projection Views (C_*) for UI/API.
- EML (Entity Manipulation Language) for programmatic BO access.
- Validations for business rules, Determinations for automatic values.
- Actions for business operations beyond CRUD.
- Feature Control for dynamic field/action availability.
- Draft for intermediate storage during complex input.
- Use
IN LOCAL MODEfor access without authorization check. FAILEDandREPORTEDfor error handling and messages.- Strict Mode (
strict ( 2 )) for best-practice validation. - Combine with CDS Views for the data model.