RAP (RESTful ABAP Programming) est le modèle de programmation moderne pour les applications transactionnelles dans SAP. Il constitue la base des applications SAP Fiori, des services OData et du développement Cloud sur SAP BTP.
Concepts fondamentaux
- Business Object (BO) : Objet métier avec données et comportement
- CDS View : Modèle de données (voir CDS Views)
- Behavior Definition (BDEF) : Déclare le comportement (CRUD, Actions, Validations)
- Behavior Implementation (BIL) : Implémente le comportement en ABAP
Architecture RAP
┌─────────────────────────────────────────────┐│ 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
| Aspect | Managed | Unmanaged |
|---|---|---|
| CRUD | Automatique par le framework | Implémentation manuelle |
| Transactions | Contrôlé par le framework | Contrôle propre |
| Effort | Faible | Plus élevé |
| Flexibilité | Opérations standard | Contrôle total |
| Recommandé pour | Nouveaux développements | Intégration legacy |
Exemple : Scénario Managed
1. Table de base de données
@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{ // Opérations standard create; update; delete;
// Mapping de champs pour la base de données field ( readonly ) TravelId; field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
// Numérotation automatique 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. " Lire les données actuelles READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel) FAILED failed.
" Feature-Control basé sur le statut 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. " Définir le statut sur '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.
" Retourner le résultat 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. " Lire les données 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). " La date de fin doit être après le début 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 = 'La date de fin doit être après la date de début" ) ) TO reported-travel. ENDIF.
" Le début ne doit pas être dans le passé 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 = 'La date de début ne peut pas être dans le passé" ) ) 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).
" Vérifier les clients 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 = 'Le client est requis" ) ) TO reported-travel. ENDIF. ENDLOOP. ENDMETHOD.
METHOD setStatusNew. " Définir le statut sur 'Open' lors de la création 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 = 'Mis à jour" ) ) 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).Éléments de Behavior
Actions
" Instance-Action (sur une ligne)action acceptTravel result [1] $self;
" Static Action (sans instance)static action createFromTemplate result [1] $self;
" Factory Action (crée une nouvelle instance)factory action copyTravel [1];
" Avec paramètresaction setStatus parameter ZA_StatusParameter result [1] $self;Validations
" Lors de Savevalidation validateDates on save { field BeginDate, EndDate; }
" Lors de Modify (vérification immédiate)validation validatePrice on modify { field TotalPrice; }
" Draft-Validationsdraft validation validateConsistency on save;Determinations
" Lors de Createdetermination setDefaults on modify { create; }
" Lors de modification de champdetermination calculateTotal on modify { field Quantity, Price; }
" Lors de Savedetermination generateNumber on save { create; }Feature Control
" Features globauxfield ( readonly ) TravelId;field ( mandatory ) CustomerId;field ( readonly : update ) AgencyId;
" Instance-Features (dynamique)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 (automatiquement disponibles) draft action Edit; draft action Activate optimized; draft action Discard; draft action Resume; draft determine action Prepare;}Classes importantes
| Classe | Description |
|---|---|
cl_abap_behavior_handler | Classe de base pour Behavior Implementation |
cl_abap_context_info | Contexte système (Date, User) |
if_abap_behv | Constantes (fc-o-enabled, mk-on) |
if_abap_behv_message | Message-Severity |
Points importants / Bonnes pratiques
- Scénario Managed pour les nouveaux développements – le framework gère le CRUD.
- Interface Views (I_*) pour le modèle de données, Projection Views (C_*) pour UI/API.
- EML (Entity Manipulation Language) pour l’accès programmatique au BO.
- Validations pour les règles métier, Determinations pour les valeurs automatiques.
- Actions pour les opérations métier au-delà du CRUD.
- Feature Control pour la disponibilité dynamique des champs/actions.
- Draft pour la sauvegarde intermédiaire lors de saisies complexes.
- Utilisez
IN LOCAL MODEpour l’accès sans vérification d’autorisation. FAILEDetREPORTEDpour la gestion d’erreurs et les messages.- Strict Mode (
strict ( 2 )) pour la validation des bonnes pratiques. - Combinez avec CDS Views pour le modèle de données.