But if you’re anything like me, you’re chomping at the bit to get neck-deep in the ABAP editor and actually crank out some code. Having worked through the above materials and a couple of my own Gateway service instances, I wanted to share some enhancement and performance-tuning thoughts to developers jumping into this product. Before we begin, did you ever notice that when you generate a Gateway service that a bunch of classes are automatically generated? You can view them in the SEGW transaction, inside your service under the heading “Runtime Artifacts”:
We’ll make use of these classes in the below example code. Note that *_DPC classes are the base, generated classes, while *_EXT classes are subclasses that can be extended for custom purposes.
Now, on to the information!
Know Your BAPIs
If you’ve imported the definition of an RFC BAPI, one of the first things you should do is check the definition for a “max_rows” importing parameter. A consumer of this OData service can make use of this to restrict processing both on the originating application server as well as sending less data across the wire to the consumer. Note: not all standard SAP BAPIs make use of this parameter.The most helpful scenario for this is implementing paging in your consuming application. Let’s say your service is returning a list of contracts to the consumer, and the consuming application wants a single paged subset of the total applicable contracts. The URI that calls this implementation will look something like:
/sap/opu/odata/sap/ZCONTRACT_SRV/ContractCollection?$top=3&$skip=0
(The parameter $top tells you how big the page is, and $skip tells you where you are in the list. In this example the consuming application has pages of 3 contracts apiece, and is on the first page.)
Knowing the page size and skip values tells you how many rows you need to pass to your max_rows parameter. Even if you had the system generate your data access classes through the screens, Gateway’s generated *_DPC classes can be extended via the *_DPC_EXT classes which are also generated at service creation. For our purposes, the CONTRACTCOLLECTI_GET_ENTITYSET method is where we extend the base class to ensure we pull limited data back.
Here’s some simple sample code:
METHOD CONTRACTCOLLECTI_GET_ENTITYSET.
CHECK it_order[] IS INITIAL. “See note below
DATA: lv_max_rows TYPE bapimaxrow,
lv_lower_bound TYPE i,
lv_upper_bound TYPE i.
“is_paging is the structure that holds the $top and $skip parameters
lv_max_rows = is_paging-top + is_paging-skip.
“this is a contrived FM – substitute your own!
“note that *_DPC class generates the instance attribute t_contract
“based on the service implementation in SEGW
CALL FUNCTION ‘BAPI_CONTRACTLIST_GET’
EXPORTING
max_rows = lv_max_rows
“your other parameters may need to be here
TABLES
t_contract = t_contract.
“Now if $skip is a nonzero number, you can remove that many
“rows from the top of the table and return the result
lv_lower_bound = is_paging-skip.
IF lines( t_contract ) > is_paging-skip + is_paging-top.
lv_upper_bound = is_paging-skip + is_paging-top.
ELSE.
lv_upper_bound = lines( t_contract ).
ENDIF.
LOOP AT t_contract INTO ls_contract
FROM lv_lower_bound TO lv_upper_bound.
“Logic goes here to move fields to parameter table et_entityset
ENDLOOP.
ENDMETHOD.
Two things to note:
- Even if you implement your own data population logic without a call to an RFC, if you use ABAP Open SQL to retrieve records you can use the clause “UP TO lv_max_rows ROWS” in your SQL and keep the rest of the logic exactly the same.
- If the $orderby option is filled, you CANNOT use this logic. See the very first CHECK in the sample method.
$filter and $select
The URI can also accommodate two other options that can drastically reduce the applicable recordset. $filter allows you to see any selection options that could reduce the total record count of the result, while $select provides the same functionality as the SELECT clause of an SQL statement: defining the width and properties of the result.There are many ways for which these things could be applicable in a number of RFC or custom code scenarios, but here I’ll show you how to retrieve these options programmatically. We can use the same redefinition of method as above, as this is applicable to any *_GET_ENTITY or *_GET_ENTITYSET methods in the DPC classes.
METHOD CONTRACTCOLLECTI_GET_ENTITYSET.
“First, retrieve the $select fields
“This is relatively easy, provided by a helper method.
“After invocation, lt_select contains a list of all
“fields needed for the corresponding SELECT statement,
“and to define which fields should be mapped back into
“the et_entityset exporting parameter.
DATA: lt_select TYPE /IWBEP/T_MGW_TECH_FIELD_NAMES.
lt_select = io_tech_request_context->get_select( ).
“Now the $filter data.
“This comes into the method as importing parameter
“it_filter_select_options. If we were filtering by
“contract ID, we could use code as follows:
DATA: ls_filter_select_options TYPE /iwbep/s_mgw_select_option,
lt_contract_range TYPE RANGE OF contract_id,
ls_contract_range LIKE LINE OF lt_contract_range,
ls_select_option TYPE /iwbep/s_cod_select_option.
“Since any number of select options can be in the table,
“we have to examine it and pull out the relevant information
“for the contract_id range.
LOOP AT it_filter_select_options INTO ls_filter_select_options.
IF ls_filter_select_options-property = ‘ContractID’.
LOOP AT ls_filter_select_options-select_options
INTO ls_select_option.
MOVE-CORRESPONDING ls_select_option TO ls_contract_range.
APPEND ls_contract_range TO lt_contract_range.
ENDLOOP.
ENDIF.
ENDLOOP.
ENDMETHOD.
Customizing Calls to Standard RFCs
EXPORTING
iv_entity_name = iv_entity_name
iv_entity_set_name = iv_entity_set_name
iv_source_name = iv_source_name
it_filter_select_options = lt_filter_select_options
is_paging = is_paging
it_key_tab = it_key_tab
it_navigation_path = it_navigation_path
it_order = it_order
iv_filter_string = iv_filter_string
iv_search_string = iv_search_string
io_tech_request_context = io_tech_request_context
IMPORTING
et_entityset = et_entityset
es_response_context = es_response_context.
Summary
- Tips for making sure that your NetWeaver Gateway service is configured for performance
- Tips for making sure that your SAPUI5 application makes good use of your Gateway services
- Writing ABAP code to consume an external RESTful web service and expose it to Gateway