ABAP RAP Fundamentals: RESTful ABAP Programming

Category
ABAP-Statements
Published
Author
Johannes

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

AspectManagedUnmanaged
CRUDAutomatic by frameworkManually implemented
TransactionsFramework-controlledFull control
EffortLowHigher
FlexibilityStandard operationsFull control
Recommended forNew developmentsLegacy integration

Example: Managed Scenario

1. Database Table

@EndUserText.label : 'Travel'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
define 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 Travel
persistent table ztravel
lock master
authorization 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_O4

EML – 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 parameters
action setStatus parameter ZA_StatusParameter result [1] $self;

Validations

" On save
validation validateDates on save { field BeginDate, EndDate; }
" On modify (immediate validation)
validation validatePrice on modify { field TotalPrice; }
" Draft validations
draft validation validateConsistency on save;

Determinations

" On create
determination setDefaults on modify { create; }
" On field change
determination calculateTotal on modify { field Quantity, Price; }
" On save
determination generateNumber on save { create; }

Feature Control

" Global features
field ( 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 Travel
persistent table ztravel
draft table zdraft_travel
lock master
total etag LastChangedAt
authorization 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

ClassDescription
cl_abap_behavior_handlerBase class for Behavior Implementation
cl_abap_context_infoSystem context (date, user)
if_abap_behvConstants (fc-o-enabled, mk-on)
if_abap_behv_messageMessage 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 MODE for access without authorization check.
  • FAILED and REPORTED for error handling and messages.
  • Strict Mode (strict ( 2 )) for best-practice validation.
  • Combine with CDS Views for the data model.