Im ABAP RESTful Application Programming Model (RAP) bilden wir Business Objects normalerweise auf Basis von CDS View Entities und persistenten Tabellen ab. Doch es gibt Situationen, in denen die Daten gar nicht in der SAP-Datenbank liegen. Das ist zum Beispiel der Fall, wenn Informationen aus einem externen Service, aus einer RFC-Schnittstelle oder aus einer Berechnung „on the fly“ bereitgestellt werden sollen. Für solche Szenarien gibt es die Custom Entity.
Eine Custom Entity ist eine virtuelle Datenquelle. Sie sieht aus wie ein CDS View, besitzt aber keine FROM-Klausel und keine eigene Persistenz. Stattdessen muss der Entwickler selbst bestimmen, wie die Daten bereitgestellt werden.
Die Definition einer Custom Entity erfolgt in CDS. Im folgenden Beispiel wird eine Flugliste definiert:
@EndUserText.label: 'Flugliste (Custom Entity)'
define custom entity ZCE_FLIGHT_LIST
{
key carrier_id : abap.char(3);
key connection_id: abap.numc(4);
city_from : abap.char(20);
city_to : abap.char(20);
flight_date : abap.dats;
price : abap.curr(10,2);
}
Wichtig ist, dass Schlüsselattribute zwingend erforderlich sind, auch wenn keine Tabelle im Hintergrund existiert.
Damit RAP die Custom Entity nutzen kann, wird eine Behavior Definition benötigt. Diese legt fest, welche Operationen erlaubt sind. Im Beispiel werden ein einfaches Lesen sowie eine Action „book“ vorgesehen.
define behavior for custom entity ZCE_FLIGHT_LIST
implementation in class ZBP_CE_FLIGHT_LIST unique
{
retrieve;
action ( features : instance ) book;
}
retrieve;
Implementierung im Handler über IF_RAP_QUERY_PROVIDER~select.
action ( features : instance ) book;
action ( features : static ) refresh;
Implementierung im Handler über IF_RAP_ACTION_HANDLER~execute.
function import getStatistics result [1] ZCE_FLIGHT_STATS;
Implementierung ebenfalls über IF_RAP_ACTION_HANDLER~execute, jedoch als Funktionsaufruf ohne Instanzbindung.
draft;
Implementierung über Methoden für prepare, activate, discard in der Behavior-Implementierungsklasse.
validation validate_price on modify { field price; }
Implementierung im Handler über IF_RAP_VALIDATION~execute.
determination set_defaults on modify { field city_from; }
Implementierung im Handler über IF_RAP_DETERMINATION~execute.
authorization master ( instance );
Implementierung im Handler über IF_RAP_AUTHORIZATION~get_instance_authorizations.
| Merkmal | Custom Entity | Root Custom Entity |
| Rolle im BO | Baustein oder Child | Einstiegspunkt (Root) |
| Persistenz | Keine | Keine |
| Pflichtoperation | retrieve | retrieve, optional draft |
| Erweiterungen | action, function import | action, function import, draft, validation, determination, authorization |
| Draft | Nicht verfügbar | Verfügbar (manuell implementiert) |
| Navigation | Kann Child sein | Kann Child Entities haben |
| OData Exposition | Nur eingebunden, nicht Root | Einstiegspunkt im Service |
Die eigentliche Logik steckt in der Behavior-Implementation-Klasse. Dort liefert die Methode if_rap_query_provider~select die Daten zurück. Diese können aus einem Service, einer Berechnung oder – wie hier – einfach als Dummy-Werte erzeugt werden.
CLASS zbp_ce_flight_list DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_rap_query_provider.
INTERFACES if_rap_action_handler.
ENDCLASS.
CLASS zbp_ce_flight_list IMPLEMENTATION.
METHOD if_rap_query_provider~select.
DATA lt_result TYPE TABLE OF zce_flight_list.
APPEND VALUE #( carrier_id = 'LH'
connection_id = '0405'
city_from = 'Berlin'
city_to = 'New York'
flight_date = sy-datum + 7
price = '899.00' ) TO lt_result.
APPEND VALUE #( carrier_id = 'AF'
connection_id = '1234'
city_from = 'Paris'
city_to = 'Tokyo'
flight_date = sy-datum + 10
price = '1299.00' ) TO lt_result.
io_response->set_data( lt_result ).
ENDMETHOD.
METHOD if_rap_action_handler~execute.
LOOP AT it_requests ASSIGNING FIELD-SYMBOL(<req>).
APPEND VALUE #( %key = <req>-keys[ 1 ]
%param = VALUE zce_flight_list(
carrier_id = <req>-keys[ 1 ]-carrier_id
connection_id = <req>-keys[ 1 ]-connection_id
city_from = 'Booking Confirmed'
city_to = ''
flight_date = sy-datum
price = '0.00' ) ) TO et_results.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
Damit die Custom Entity nach außen sichtbar wird, benötigt man eine Service Definition. Diese legt fest, dass die Entity exponiert wird:
define service ZUI_FLIGHT_CE {
expose ZCE_FLIGHT_LIST;
}
ABAP Core Data Services (CDS) sind eine moderne Möglichkeit in SAP ABAP, Datenbankabfragen und Datenmodelle zu definieren.
Sie sind ein semantisches Schichtmodell auf der Datenbank, mit dem man Daten deklarativ beschreibt, statt rein prozedural in ABAP zu programmieren.