RAP (RESTful ABAP Programming) es el modelo de programación moderno para aplicaciones transaccionales en SAP. Forma la base para SAP Fiori Apps, servicios OData y desarrollo en la nube en SAP BTP.
Conceptos Fundamentales
- Business Object (BO): Objeto de negocio con datos y comportamiento
- CDS View: Modelo de datos (ver CDS Views)
- Behavior Definition (BDEF): Declara el comportamiento (CRUD, Actions, Validations)
- Behavior Implementation (BIL): Implementa el comportamiento en ABAP
Arquitectura RAP
┌─────────────────────────────────────────────┐│ Fiori UI │├─────────────────────────────────────────────┤│ Servicio OData │├─────────────────────────────────────────────┤│ Capa de Projection (C_*) │├─────────────────────────────────────────────┤│ Capa Business Object (I_*) ││ ┌─────────────┐ ┌────────────────────┐ ││ │ CDS View │ │ Behavior │ ││ │ (Datos) │ │ Definition (BDEF) │ ││ └─────────────┘ └────────────────────┘ ││ │ ││ ┌───────────▼───────────┐ ││ │ Behavior │ ││ │ Implementation (BIL) │ ││ └───────────────────────┘ │├─────────────────────────────────────────────┤│ Base de Datos │└─────────────────────────────────────────────┘Escenario Managed vs. Unmanaged
| Aspecto | Managed | Unmanaged |
|---|---|---|
| CRUD | Automático por el framework | Implementar manualmente |
| Transacciones | Controladas por framework | Control propio |
| Esfuerzo | Bajo | Mayor |
| Flexibilidad | Operaciones estándar | Control total |
| Recomendado para | Nuevos desarrollos | Integración legacy |
Ejemplo: Escenario Managed
1. Tabla de Base de Datos
@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{ // Operaciones estándar create; update; delete;
// Mapeo de campos para base de datos field ( readonly ) TravelId; field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
// Numeración automática 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. " Leer datos actuales READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel) FAILED failed.
" Feature-Control basado en estado 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. " Establecer estado a '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.
" Devolver resultado 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. " Leer datos 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 fecha de fin debe ser posterior al inicio 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 fecha de fin debe ser posterior a la fecha de inicio' ) ) TO reported-travel. ENDIF.
" El inicio no puede estar en el pasado 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 fecha de inicio no puede estar en el pasado' ) ) 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).
" Verificar clientes 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 = 'El cliente es obligatorio' ) ) TO reported-travel. ENDIF. ENDLOOP. ENDMETHOD.
METHOD setStatusNew. " Al crear, establecer estado en 'Open' 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
- Nombre: ZUI_TRAVEL_O4- Tipo de Binding: 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 = 'Actualizado' ) ) 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).Elementos de Behavior
Actions
" Action de instancia (sobre una fila)action acceptTravel result [1] $self;
" Action estática (sin instancia)static action createFromTemplate result [1] $self;
" Factory Action (crea nueva instancia)factory action copyTravel [1];
" Con parámetrosaction setStatus parameter ZA_StatusParameter result [1] $self;Validations
" En Savevalidation validateDates on save { field BeginDate, EndDate; }
" En Modify (verificación inmediata)validation validatePrice on modify { field TotalPrice; }
" Validations de Draftdraft validation validateConsistency on save;Determinations
" En Createdetermination setDefaults on modify { create; }
" En cambio de campodetermination calculateTotal on modify { field Quantity, Price; }
" En Savedetermination generateNumber on save { create; }Feature Control
" Features globalesfield ( readonly ) TravelId;field ( mandatory ) CustomerId;field ( readonly : update ) AgencyId;
" Features de instancia (dinámicos)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 (disponibles automáticamente) draft action Edit; draft action Activate optimized; draft action Discard; draft action Resume; draft determine action Prepare;}Clases Importantes
| Clase | Descripción |
|---|---|
cl_abap_behavior_handler | Clase base para Behavior Implementation |
cl_abap_context_info | Contexto del sistema (Fecha, Usuario) |
if_abap_behv | Constantes (fc-o-enabled, mk-on) |
if_abap_behv_message | Message-Severity |
Notas Importantes / Mejores Prácticas
- Escenario Managed para nuevos desarrollos - el framework gestiona CRUD.
- Interface Views (I_*) para modelo de datos, Projection Views (C_*) para UI/API.
- EML (Entity Manipulation Language) para acceso programático al BO.
- Validations para reglas de negocio, Determinations para valores automáticos.
- Actions para operaciones de negocio más allá de CRUD.
- Feature Control para disponibilidad dinámica de campos/acciones.
- Draft para almacenamiento intermedio en entradas complejas.
- Usa
IN LOCAL MODEpara acceso sin verificación de autorización. FAILEDyREPORTEDpara manejo de errores y mensajes.- Strict Mode (
strict ( 2 )) para validación de mejores prácticas. - Combina con CDS Views para el modelo de datos.