Hi all,
In SAP's ABAP RESTFULL Application Programming Model (RAP), a function is a non-standard operation defined in behavior definitions. Functions are implemented in the ABAP behavior pool class and are used to return information without modifying the state of the business object.
Here are some key points about functions in RAP:
Function in RAP is a custom read-operation that is part of business logic.
Functions perform calculations or reads on business objects without causing any side effects. Functions don't issue any locks on database tables, and you can't modify or persist any data computed in a function implementation.
Functions are specified as nonstandard operations in behavior definitions and are implemented in the ABAP behavior pool.
We have 3 types of functions.
Note: You can't define authorization control or feature control for functions.
Basically, I have taken 2 database tables.
Step 1: - Header table.
@EndUserText.label : 'header table'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zspfli_t_header {
key client : abap.clnt not null;
key carrid : abap.char(3) not null;
key connid : abap.numc(4) not null;
country_fly : abap.char(3);
city_from : abap.char(20);
airfrom : abap.char(3);
}
Step 2: - Item table
@EndUserText.label : 'item table'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zflight_t_item1 {
key client : abap.clnt not null;
key carrid : abap.char(3) not null;
key connid : abap.numc(4) not null;
key fdate : abap.dats not null;
@Semantics.amount.currencyCode : 'zflight_t_item1.p_currency'
price : abap.curr(15,2);
p_currency : abap.cuky;
planetype : abap.char(10);
seat_max : abap.int4;
}
We have some records in these 2 tables.
After that I have created interface view for both header table and item table.
Step 3: - This is my root entity.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'header details'
define root view entity zi_flight_header01 as select from zspfli_t_header
composition[0..*] of zi_flight_item01 as _item
{
key carrid as Carrid,
key connid as Connid,
country_fly as CountryFly,
city_from as CityFrom,
airfrom as Airfrom,
_item
}
Step 4: - This is my child entity.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'item table details'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity zi_flight_item01 as select from zflight_t_item1
association to parent zi_flight_header01 as _header
on $projection.Carrid = _header.Carrid and
$projection.Connid = _header.Connid
{
key carrid as Carrid,
key connid as Connid,
key fdate as Fdate,
@Semantics.amount.currencyCode: 'PCurrency'
price as Price,
p_currency as PCurrency,
planetype as Planetype,
seat_max as SeatMax,
_header
}
And I have created a projection view for these basic views.
Step 5: - Projection view for Header table.
@EndUserText.label: 'header projection view'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.allowExtensions: true
define root view entity zc_header_flight
provider contract transactional_query as projection on zi_flight_header01
{
key Carrid,
key Connid,
CountryFly,
CityFrom,
Airfrom,
/* Associations */
_item
}
Step 6: - Projection view for Item table.
@EndUserText.label: 'projection view for item'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view entity zc_flight_item
provider contract transactional_query as projection on zi_flight_item01
{
key Carrid,
key Connid,
key Fdate,
Price,
PCurrency,
Planetype,
SeatMax,
/* Associations */
_header
}
Step 7: - After that I have created behavior definition.
managed implementation in class zbp_i_flight_header01 unique;
strict ( 2 );
define behavior for zi_flight_header01 alias header
persistent table zspfli_t_header
lock master
authorization master ( global )
//etag master <field_name>
{
create;
update;
delete;
function fun_action result [1] $self;
field ( readonly ) Carrid, Connid;
association _item { create; }
mapping for ZSPFLI_T_HEADER
{
Carrid = carrid;
CityFrom = city_from;
Connid = connid;
CountryFly = country_fly;
Airfrom = airfrom;
}
}
define behavior for zi_flight_item01 //alias <alias_name>
persistent table zflight_t_item1
lock dependent by _header
authorization dependent by _header
//etag master <field_name>
{
update;
delete;
field ( readonly ) Carrid, Connid, Fdate;
association _header;
}
Step 8: - Implementation class.
CLASS lhc_zi_flight_header01 DEFINITION INHERITING FROM cl_abap_behavior_handler.
PUBLIC SECTION.
*INTERFACES if_oo_adt_classrun.
PRIVATE SECTION.
METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION
IMPORTING REQUEST requested_authorizations FOR zi_flight_header01 RESULT result.
METHODS fun_action FOR READ
IMPORTING keys FOR FUNCTION zi_flight_header01~fun_action RESULT result.
ENDCLASS.
CLASS lhc_zi_flight_header01 IMPLEMENTATION.
METHOD get_global_authorizations.
ENDMETHOD.
METHOD fun_action.
READ ENTITIES OF zi_flight_header01 IN LOCAL MODE ENTITY header
FIELDS ( carrid connid CountryFly CityFrom Airfrom ) WITH CORRESPONDING #( keys )
RESULT DATA(lt_result)
FAILED DATA(lt_failed).
if lt_result is NOT INITIAL.
loop AT lt_result ASSIGNING FIELD-SYMBOL(<ls_result>).
if <ls_result>-Airfrom = 'MYS' .
<ls_result>-Airfrom = 'MD'.
ENDIF.
APPEND VALUE #( %tky = <ls_result>-%tky
%param = CORRESPONDING #( <ls_result> ) ) TO result.
ENDLOOP.
ENDIF.
ENDMETHOD.
ENDCLASS.
Step 9: - And also, projection view to consumption view.
projection;
strict ( 2 );
define behavior for zc_header_flight //alias <alias_name>
{
use create;
use update;
use delete;
use function fun_action;
}
Step 10: - After that I have created service definition and service binding
@EndUserText.label: 'service definition for flight header'
define service Zservice_flight_h {
expose zi_flight_header01;
expose zi_flight_item01;
}
Step 11 : - Service Binding.
After that this will be my output.
Step 12: - But to function method calling I have taken another class it is inhering class classrun.
CLASS zcl_test_ga DEFINITION
PUBLIC
INHERITING FROM cl_demo_classrun
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS main REDEFINITION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_test_ga IMPLEMENTATION.
METHOD main.
"Read operation executing a function
READ ENTITIES OF zi_flight_header01
ENTITY header
EXECUTE fun_action
FROM VALUE #( ( %tky-Carrid = 'LH'
%tky-Connid = '0400' ) )
RESULT Data(LT_result)
FAILED FINAL(faiLED)
REPORTED FINAL(reported).
OUT->write( LT_result ).
ENDMETHOD.
ENDCLASS.
Conclusion.
By using function, basically we can read the data from database and if it wants to modify the records we can modify in transactional buffer records only. We can't modify the database table records by using function methods.
Output :--> console.
Output :---> database table