1. Using Abstract Entities for Non-Standard RAP BO Operations.
This short overview of abstract entities concept in the context of non-standard RAP business object operations. It outlines their purpose, advantages, and implementation strategies, emphasizing their role in enhancing modularity and flexibility in data modeling.
Purpose
Abstract entities are Core Data Services (CDS) constructs specifically designed to model complex input parameters for non-standard RAP BO operations(actions and functions).
Database Independence
One of the key features of abstract entities is their independence from database persistence. They are particularly suited for parameter modeling and give possibility to redefine parameters on next modelling level.
Reusability
Abstract entities promote reusability across multiple operations. This characteristic enables developers to adopt a more modular approach, allowing the same abstract entity to be utilized in different contexts without the need for redundant definitions.
Parameter Flexibility
These entities support complex structures, including multi-level nested components. This flexibility allows for more sophisticated data representations and enhances the capability to handle intricate business logic.
Binding
Unlike traditional entities, abstract entities are not bound to specific BO nodes. They provides greater adaptability in how they are integrated into various operations.
Improved Separation of Concerns
By decoupling input parameter modeling from the actual business logic, abstract entities facilitate a clearer separation of concerns. This simplification in design leads to more maintainable and understandable code, as the focus can be placed on each aspect of the application independently.
In conclusion, abstract entities serve as a powerful tool for modeling complex input parameters in non-standard RAP BO operations.
2. Implementation details.
I want to highlight how to effectively use abstract entities in ABAP development. One of their key applications is for typing, particularly for action parameters in RAP actions. Let’s begin with a straightforward example.
We make a simple abstract entity with four fields.
@EndUserText.label: 'ABSTRACT ENTITY'
define root abstract entity ZPRU_ABS_ENTITY
{
ABSTRACTENTITYNAME : char40;
SURNAME : char40;
AGE : int4;
EMAIL : char40;
CHILD : composition [ * ] of ZPRU_ABS_CHILD;
CHILD_2: composition [ * ] of ZPRU_ABS_CHILD_2;
}
Next, I created a RAP business object with a root entity view (the specifics of which aren’t important for this example) and defined the ‘sendEntity’ action with an input parameter of type ZPRU_ABS_ENTITY.
Let’s have a look at action definition:
managed implementation in class zbp_pru_root_entity unique;
strict ( 2 );
define behavior for ZPRU_ROOT_ENTITY alias ROOT
persistent table zpru_dn
lock master
authorization master ( instance )
{
create;
update;
delete;
field ( readonly ) dn_no, freq, prod;
//Flat
action sendEntity parameter ZPRU_ABS_ENTITY;
// Deep
action sendEntity2 deep parameter ZPRU_ABS_ENTITY;
// Deep Table
action sendEntity3 deep table parameter ZPRU_ABS_ENTITY;
}
Right now, let’s check RAP business object implementation class.
CLASS lhc_root DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR root RESULT result.
METHODS sendentity2 FOR MODIFY
IMPORTING keys FOR ACTION root~sendentity2.
METHODS sendentity FOR MODIFY
IMPORTING keys FOR ACTION root~sendentity.
METHODS sendentity3 FOR MODIFY
IMPORTING keys FOR ACTION root~sendentity3.
ENDCLASS.
CLASS lhc_root IMPLEMENTATION.
METHOD get_instance_authorizations.
ENDMETHOD.
METHOD sendentity2.
DATA(lv_deep_field_from_abs_entity) = keys[ 1 ]-%param-child[ 1 ]-abstractchildname.
ENDMETHOD.
METHOD sendentity.
DATA(lv_field_from_abs_entity) = keys[ 1 ]-%param-abstractentityname.
ENDMETHOD.
METHOD sendentity3.
DATA(lv_deep_table_field) = keys[ 1 ]-%param[ 1 ]-child[ 1 ]-abstractchildname.
ENDMETHOD.
ENDCLASS.
Derived type:
As a result, you’ll see the KEYS table, where each row contains a %PARAM component. This component is typed as the structure ZPRU_ABS_ENTITY.
The next step is to demonstrate the use of the ‘deep parameter AbstractBDEF’ and the ‘deep table parameter AbstractBDEF’ in defining a BDEF action parameter.
To do this, we need to extend the abstract entity by adding a BDEF of type Abstract with a hierarchy.
First, I added the ‘root’ keyword to the abstract entity:
One important note: when adding a BDEF to an abstract entity, we initiate the creation of an abstract business object. As a result, we need to construct this business object in a way that’s quite similar to how we build standard RAP business objects. This is why we use keywords like ‘root’, ‘composition’, and ‘association to parent.’
I also created a new abstract entity, ZPRU_ABS_CHILD. Then, I added mutual associations between ZPRU_ABS_ENTITY as the root and ZPRU_ABS_CHILD as the child.
Then, I’ve created BDEF with ZPRU_ABS_ENITY as root entity and Abstract implementation type:
Let’s overview new abstract BDEF:
abstract;
strict ( 2 );
with hierarchy;
define behavior for ZPRU_ABS_ENTITY alias ABS
{
association CHILD;
association CHILD_2;
}
define behavior for ZPRU_ABS_CHILD alias CHILD
{
association ROOT;
}
define behavior for zpru_abs_child_2 {
association third_level;
}
There are 3 main points:
- add keyword ‘with hierarchy’ to make BDEF opt to deep expanding.
- recreate RAP BO composition tree, add root entity and child entity.
- explicitly mark association to ZPRU_ABS_CHILD.
Finally, I’ve added addition keyword ‘deep’ to action definition to expand action parameter type.
Let’s have a look into typing:
%PARAM typing:
You can notice that to component %PARAM a new nested table with the name CHILD has been added. It’s an effect of keyword ‘deep’ in action parameter definition. Component CHILD has type of table due to cardinality [ * ] in definition of composition in abstract root entity ZPRU_ABS_ENTITY.
Last topic is about addition ‘deep table’ to action parameter definition.
Let’s add it:
Hence, let’s check what has been changed in typing:
As you can see component %PARAM became table, before it was a structure. This is the effect of keyword ‘table’ in action parameter definition.
Lastly, the same principles apply to typing action output parameters. However, one key difference is that we can’t use the ‘deep’ addition when defining output parameters. As a result, the %PARAM component will be incorporated into the output’s derived type as a structure.
A table with summarizing: