Working Example for SAP Netweaver Gateway Beginners:
SAP NetWeaver Gateway is used to share data between SAP
and Non-SAP Systems using its ODATA Capabilities.
SAP NetWeaver Gateway offers development and
generation tools to create OData services to a variety of client development
tools. Put simply, it establishes a connection between SAP Business Suite data
and target clients, platforms, and programming framework.
Transactions:
SE11 - Data Dictionary
SE24 - Class Builder
SEGW - SAP Netweaver Gateway Service Builder
/IWFND/GW_CLIENT - SAP Gateway Client
/IWFND/ERROR_LOG - SAP Gateway: Error Log
/IWFND/MAINT_SERVICE - Activate and Maintain Services
Objective:
Will be creating two tables, Header Table and Item
Table and do the possible CRUD operations using netweaver gateway to understand
how the implementation (redefinition) of methods happens to achieve the needed
functionality. In turn, to understand what are the methods need to be
implemented to achieve the supported functionalities.
Steps:
1. Go to SE11. Create two tables. Make them
header and Item using foreign key relationship.
2. Go to SEGW. Create a project. Create
Entities and Entitysets. Define association between the two (Header and Item)
entities.
3. Go to SE24 and redefine the relevant
methods of the data provider class.
4. Go to gateway client (TCode:
/IWFND/GW_CLIENT). And do the operations giving relevant HTTP Method and URI.
STEP
1:
Go to SE11 and create two tables as below.
ZMA_GW_EMP: Employees
ZMA_GW_EMP_DEP: Dependents
All the below gateway operations will be performed
using these tables going ahead.
Operations:
GET_ENTITY
|
To get one employee data from header table
|
GET_ENTITYSET
|
To get multiple employees data from header table
|
CREATE_ENTITY
|
To create one employee
|
UPDATE_ENTITY
|
To update one employee
|
DELETE_ENTITY
|
To delete one employee
|
GET_EXPANDED_ENTITY
|
To get header and Dependent data of an employee at a
time
|
GET_EXPANDED_ENTITYSET
|
To get header and Dependent data of multiple
employees at a time
|
CREATE_DEEP_ENTITY
|
To create employee and dependents at a time
|
STEP2:
Go to Transaction code SEGW and crate a project
ZMA_EMPS_DEMO.
Right click on Data Model and Import DDIC Structure.
Provide entity name and
DDIC table name and press Next.
Select the fields required.
Select the EMPLOYEE field as Key and Finish.
Do the same with Item table as in below three
screenshots.
It will show up this way in the hierarchy in SEGW.
Above are the two entities created and the two
corresponding entity sets.
Create an association between the two entities as shown below.
After that press the Generate runtime objects button to
create Runtime artifacts.
In Service maintenance, Generated service need to be
registered. Here this can be two ways.
1. Both Dev client and Gateway client can be
on the same server or can be on different servers.
2. Log into the tcode /IWFND/MAINT_SERVICE
accordingly and register the service.
It is done with tcode SEGW now. Go to TCode /IWFND/GW_CLIENT and try to get the
metadata using below URI.
URI: /sap/opu/odata/sap/ZMA_EMPS_DEMO_SRV/$metadata
Implement methods in the class ZCL_ZMA_EMPS_DEMO_DPC_EXT
to get the functionalities working.
GET_ENTITY:
EMP_DATASET_GET_ENTITY. This method should be redefined
as below.
IT_KEY_TAB: This importing parameter holds the key
value entered in the url.
METHOD emp_dataset_get_entity.
DATA:lk_key_tab TYPE /iwbep/s_mgw_name_value_pair.
READ TABLE it_key_tab INTO lk_key_tab WITH KEY name = 'Employee'.
IF sy-subrc IS INITIAL.
SELECT SINGLE *
FROM zma_gw_emp
INTO er_entity
WHERE employee = lk_key_tab-value.
ENDIF.
ENDMETHOD.
Testing:
HTTP Method: GET
URI: /sap/opu/odata/sap/ZMA_EMPS_DEMO_SRV/Emp_DataSet('00000001')
OUTPUT:
To get the response in JSON Format:
HTTP Method: GET
URI:
/sap/opu/odata/sap/ZMA_EMPS_DEMO_SRV/Emp_DataSet('00000001')?$format=json
METHOD emp_dataset_get_entityset.
DATA:li_tech_order TYPE /iwbep/t_mgw_tech_order,
lk_tech_order TYPE /iwbep/s_mgw_tech_order,
li_ord_tab TYPE abap_sortorder_tab,
lk_ord_tab TYPE abap_sortorder,
lo_filter TYPE REF TO /iwbep/if_mgw_req_filter,
lt_sel_opt TYPE /iwbep/t_mgw_select_option,
ls_emp_selopt TYPE /iwbep/s_mgw_select_option.
lo_filter = io_tech_request_context->get_filter( ).
lt_sel_opt = lo_filter->get_filter_select_options( ).
READ TABLE lt_sel_opt INTO ls_emp_selopt WITH KEY property = 'EMPLOYEE'.
SELECT *
FROM zma_gw_emp
INTO TABLE et_entityset
WHERE employee IN ls_emp_selopt-select_options.
li_tech_order = io_tech_request_context->get_orderby( ).
LOOP AT li_tech_order INTO lk_tech_order.
lk_ord_tab-name = lk_tech_order-property.
IF lk_tech_order-order = 'desc'.
lk_ord_tab-descending = 'X'.
ENDIF.
APPEND lk_ord_tab TO li_ord_tab.
CLEAR lk_ord_tab.
ENDLOOP.
IF li_ord_tab IS NOT INITIAL.
SORT et_entityset BY (li_ord_tab).
ENDIF.
DATA:ls_header TYPE ihttpnvp.
ls_header-name = 'my-custom-message'.
ls_header-value = '{msg_typ:S, desc: Data Retrieved}'.
/iwbep/if_mgw_conv_srv_runtime~set_header( ls_header ).
ENDMETHOD.
If there is a filter given in the URI: the yellow highlighted lines need
to be added in the code
HTTP Method: GET
URI:
/sap/opu/odata/sap/ ZMA_EMPS_DEMO_SRV /Emp_DataSet?$filter=Employee eq
'00000001'
If there is order by added in the URI: Code lines
highlighted in pink need to be added.
HTTP Method: GET
URI:
/sap/opu/odata/sap/ZMA_EMPS_DEMO_SRV/Emp_DataSet?$orderby=EmployeeName
desc&$format=json
If a custom message need to be passed in the response
header code lines highlighted in green should be added.
CREATE_ENTITY:
EMP_DATASET_CREATE_ENTITY: This method need to be
implemented.
METHOD emp_dataset_create_entity.
DATA:lk_gw_emp TYPE zma_gw_emp,
lk_gw_emp_upd TYPE zma_gw_emp,
lk_employee TYPE zma_gw_emp,
lo_mess_cont TYPE REF TO /iwbep/if_message_container.
*Below method call is to get the
data from the input response
io_data_provider->read_entry_data( IMPORTING es_data = lk_employee ).
IF lk_employee IS INITIAL.
SELECT * FROM zma_gw_emp
INTO lk_gw_emp
UP TO 1 ROWS
ORDER BY employee DESCENDING.
ENDSELECT.
IF sy-subrc IS INITIAL.
lk_gw_emp_upd-employee = lk_gw_emp-employee + 1.
lk_gw_emp_upd-employee_name = 'Employee Name'.
ELSE.
lk_gw_emp_upd-employee = 1.
lk_gw_emp_upd-employee_name = 'Employee Name'.
ENDIF.
IF lk_gw_emp_upd IS NOT INITIAL.
INSERT zma_gw_emp FROM lk_gw_emp_upd.
ENDIF.
ELSE.
INSERT zma_gw_emp FROM lk_employee.
ENDIF.
IF sy-subrc IS INITIAL.
er_entity-employee = lk_employee-employee.
er_entity-employee_name = lk_employee-employee_name.
COMMIT WORK.
ELSE.
ROLLBACK WORK.
ENDIF.
ENDMETHOD.
Testing Steps:
- Get the
entity first
- Press use as
Request. Simplify the input request as shown above and execute. The entry
in the table will be created.
HTTP Method: POST
URI: /sap/opu/odata/sap/ZMA_EMPS_DEMO_SRV/Emp_DataSet
This way we can get the CSRF Token which is needed for Create and Update
operations.
UPDATE_ENTITY:
EMP_DATASET_UPDATE_ENTITY: This
method needs to be redefined for update operation.
HTTP Method: PUT
URI: /sap/opu/odata/sap/ZMA_EMPS_SRV/Emp_DataSet('00000014')
METHOD emp_dataset_update_entity.
DATA: ls_user TYPE zma_gw_emp.
io_data_provider->read_entry_data( IMPORTING es_data = ls_user ).
UPDATE zma_gw_emp FROM ls_user.
IF sy-subrc IS INITIAL.
COMMIT WORK.
ELSE.
ROLLBACK WORK.
ENDIF.
ENDMETHOD.
Do test it just like CREATE.
DELETE_ENTITY:
EMP_DATASET_DELETE_ENTITY:
This
method needs to be redefined.
HTTP Method: DELETE
URI:
/sap/opu/odata/sap/ZMA_EMPS_SRV/Emp_DataSet('00000014')
GET_EXPANDED_ENTITY:
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITY:
This
method needs to be redefined.
METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity.
TYPES:BEGIN OF ty_final.
INCLUDE TYPE zma_gw_emp.
TYPES:dependents TYPE zma_t_emp_dep. “ The name of this deep table
should be same as child entityset
TYPES:END OF ty_final.
DATA:lk_final TYPE ty_final,
lk_key_tab TYPE /iwbep/s_mgw_name_value_pair,
lk_exp_tech_clause TYPE string.
* Association name should be populated into ET_EXPANDED_TECH_CLAUSES to avoid
unnecessary iterations (Execution times) occur.
lk_exp_tech_clause = 'DEPENDENT_DATASET'.
INSERT lk_exp_tech_clause INTO TABLE et_expanded_tech_clauses.
IF it_key_tab IS NOT INITIAL.
READ TABLE it_key_tab INTO lk_key_tab WITH KEY name = 'Employee'.
IF sy-subrc IS INITIAL.
SELECT SINGLE * FROM zma_gw_emp
INTO CORRESPONDING FIELDS OF lk_final
WHERE employee = lk_key_tab-value.
IF sy-subrc IS INITIAL.
SELECT * FROM zma_gw_emp_dep
INTO TABLE lk_final-dependents
WHERE employee = lk_key_tab-value.
ENDIF.
ENDIF.
ENDIF.
IF lk_final IS NOT INITIAL.
CALL METHOD me->copy_data_to_ref
EXPORTING
is_data = lk_final
CHANGING
cr_data = er_entity.
ENDIF.
ENDMETHOD.
HTTP Method: GET
URI: /sap/opu/odata/sap/ZMA_EMPS_SRV/Emp_DataSet?$filter=Employee
eq '00000001'&$expand=Dependent_Dataset&$format=json
GET_EXPANDED_ENTITYSET:
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET:
This
method need to be redefined.
METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entityset.
TYPES:BEGIN OF ty_final.
INCLUDE TYPE zma_gw_emp.
TYPES:dependent_dataset TYPE zma_t_emp_dep. “ The name of this deep table
should be same as child entityset
TYPES:END OF ty_final.
DATA:li_selection TYPE /iwbep/t_cod_select_options,
lk_selection TYPE /iwbep/s_cod_select_option,
lk_select_options TYPE /iwbep/s_mgw_select_option,
lk_key_tab TYPE /iwbep/s_mgw_name_value_pair,
li_final TYPE STANDARD TABLE OF ty_final,
li_emp_dep TYPE STANDARD TABLE OF zma_gw_emp_dep,
lk_exp_tech_clause TYPE string.
FIELD-SYMBOLS:<lk_final> TYPE ty_final.
READ TABLE it_filter_select_options INTO lk_select_options
WITH KEY property = 'Employee'.
IF sy-subrc IS INITIAL.
li_selection = lk_select_options-select_options.
ENDIF.
IF li_selection IS NOT INITIAL.
SELECT * FROM zma_gw_emp
INTO CORRESPONDING FIELDS OF TABLE li_final
WHERE employee IN li_selection.
ELSE.
SELECT * FROM zma_gw_emp
INTO CORRESPONDING FIELDS OF TABLE li_final.
ENDIF.
IF li_final IS NOT INITIAL.
LOOP AT li_final ASSIGNING <lk_final>.
SELECT * FROM zma_gw_emp_dep
INTO TABLE li_emp_dep
WHERE employee = <lk_final>-employee.
<lk_final>-dependent_dataset = li_emp_dep.
ENDLOOP.
ENDIF.
CALL METHOD me->copy_data_to_ref
EXPORTING
is_data = li_final
CHANGING
cr_data = er_entityset.
lk_exp_tech_clause = 'DEPENDENT_DATASET'.
INSERT lk_exp_tech_clause INTO TABLE et_expanded_tech_clauses.
ENDMETHOD.
HTTP Method: GET
URI:
/sap/opu/odata/sap/ZMA_EMPS_DEMO_SRV/Emp_DataSet?$expand=Dependent_Dataset&$format=json
CREATE_DEEP_ENTITY:
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY:
This
method need to be redefined.
METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.
TYPES:BEGIN OF ty_final.
INCLUDE TYPE zma_gw_emp.
TYPES:dependent_dataset TYPE zma_t_emp_dep. “ The name of this deep table
should be same as child entityset
TYPES:END OF ty_final.
DATA:ls_data TYPE ty_final,
ls_emp TYPE zma_gw_emp,
ls_emp_dep TYPE zma_gw_emp_dep,
lt_emp_dep TYPE STANDARD TABLE OF zma_gw_emp_dep.
io_data_provider->read_entry_data( IMPORTING es_data = ls_data ).
IF ls_data IS NOT INITIAL.
ls_emp-employee = ls_data-employee.
ls_emp-employee_name = ls_data-employee_name.
IF ls_emp IS NOT INITIAL.
INSERT zma_gw_emp FROM ls_emp.
ENDIF.
lt_emp_dep = ls_data-dependent_dataset.
IF lt_emp_dep IS NOT INITIAL.
INSERT zma_gw_emp_dep FROM TABLE lt_emp_dep.
ENDIF.
ENDIF.
ENDMETHOD.
HTTP Method: POST
URI: /sap/opu/odata/sap/ZMA_EMPS_SRV/Emp_DataSet
Input request:
{
"d" : {
"Employee" : "00000032",
"EmployeeName" : "Mahendra",
"Dependent_Dataset" : [
{
"Employee" : "00000032",
"DepNo" : "001",
"DepType" : "0001",
"DependentName" : "Per1"
}
]
}
}
This is all about it and in the next post, all the operations using RFC Function modules which will be widely used in real time scenarios will be discussed. Thanks.