Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
32,096
Hi All,

Introduction:


This blog post explains creation of simple sap gateway odata service having association and navigation  between entities and also we will see how to implement it through code based approach and  finally conclude with implementing of GET_EXPANDED_ENTITY  and GET_EXPANDED_ENTITY_SET.

Associations Define the relationship between two or more entity Types ( For examples ,Employee Details) .Instances of associations are grouped in Association sets.

Navigation Properties are special properties on entity Types which are bound to a specific association and can be used to refer to associations of any entity.

Finally, all instance containers (Entity sets and Association sets) are grouped in an Entity container. 

 

To display header details along with item details.


 

Procedure: 


Step 1:


Go to T_code : 'SEGW'

 



Click on create button, the popup will open.

 



 

Click on create icon and provide the name of the project name and description and package name and  click 'save'.

 



 

Step2: Create Header entity type.


For example I have created header structure.

 



 

Right click on the data model folder and import the ddic structure.

 



 

Give the entity type name and abap structure whose fields you want to import to your entity type and click on 'NEXT'.

 



 

Select the fIelds from Header table structure which you want to add to your entity type and click on 'NEXT'.

 



 

Choose the key for your  structure /entity type and entity set. For examples it is

EMP_ID click on 'FINISH'.

 



 

Step 3: Create item entity type.


For example I have created item Structure.

 



 

Right click on the data model folder and import the 'DDIC STRUCTURE'.

 



Give the entity type name and abap structure whose fields you want to import to your entity type click on 'NEXT'.

 



Select the fields from structure which you want to add to your entity type, click on 'NEXT'.

 



 

Select the key for your structure /entity type and entity set . In our examples it is EMP_ID click on 'FINISH'.

 



 

Check entity types  and entity sets.

 



 



 



 

Step 4: Creating Associations and Navigation .


Expand data model  and right click on associations  and click on create button.

 



 

In the association you have to give Association , principal  type name ,dependent entity type name and navigation property name.

Principal entity has header entity name and dependent entity has the item entity name.

Navigation property maps header entity  to item entity (Principal entity to dependent entity)

Provide navigation property name to access associated entity data in our odata URI (Create related navigation property checkbox will be checked by default) . After entering values to these fields click on 'NEXT'.

 



 

Select dependent property and click on 'NEXT'.

Dependent property will be the key relating two entities.

 



Select principle entity set and dependent entity set and click on 'FINISH'.

 



 

Finally our odata service should look like this,See navigation property is added to employee header  details entity set .Also an association and association set is created .Click on generate button.

 



 

Step5: Generate objects.


Let's generate runtime artifacts ,click on generate objects button.

 



 

It will display popup click on 'CONTINUE'.

 



 

Give local package name click on 'Local Object'.

 



 

Once generation is successful, 6 classes i.e , 2 for Data provider and 2 for Model provider and 1 for Registered service and 1 for  displayed.

 



 

Success message has to be displayed  as shown below.

 


Step6:


Now open ******_DPC_EXT class and go to edit mode.

 



 

From inherited methods node

Find /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY

CREATE_DEEP_ENTITY and right click and press redefine.

 



 

 

It's time for some coding. Implemented CREATE_DEEP_ENTITY.

Method: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY.

 



 

METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.

********** Structure ************

DATA BEGIN OF ls_order_item_data.
INCLUDE TYPE zcl_zexpand_emp_det_02_mpc=>ts_zemp_header_details.
DATA :   zemp_itemset TYPE  zcl_zexpand_emp_det_02_mpc=>tt_zemp_item,
END OF ls_order_item_data.

********** Data Declaration ***************

DATA:
ls_headerdata   TYPE zemp_head,
lt_headerdata   TYPE TABLE OF zemp_head,
lt_itemdata     TYPE TABLE OF zemp_item1,
ls_itemdata     TYPE  zemp_item1,
ls_req_itemdata TYPE zcl_zexpand_emp_det_02_mpc=>ts_zemp_item,
lemp_id         TYPE zemp_id.

********** Entity Set – HeaderSet ***********

CASE iv_entity_set_name.
WHEN 'ZEMP_HEADER_DETAILSSet'.
io_data_provider->read_entry_dataIMPORTING es_data ls_order_item_data ).
ls_headerdata-emp_id ls_order_item_data-emp_id.
ls_headerdata-emp_name =  ls_order_item_data-emp_name.
ls_headerdata-dept =  ls_order_item_data-dept.
MODIFY zemp_head FROM ls_headerdata.
APPEND  ls_headerdata TO  lt_headerdata .

**********  Data processing logic ************

LOOP AT ls_order_item_data-zemp_itemset INTO ls_req_itemdata .
MOVE-CORRESPONDING ls_req_itemdata TO ls_itemdata.
MODIFY zemp_item1 FROM ls_itemdata.
APPEND ls_itemdata TO lt_itemdata.
ENDLOOP.
IF sy-subrc EQ 0.
MODIFY zemp_item1 FROM TABLE lt_itemdata.
IF sy-subrc EQ 0.

********** Fill er_deep_entity ***********

copy_data_to_refEXPORTING is_data ls_order_item_data
CHANGING  cr_data er_deep_entity ).
ENDIF.
ENDIF.
ENDCASE.
ENDMETHOD.


Implemented GET_EXPANDED_ENTITY method.


Method: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITY.


 



 

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity.

********** Structure ************

DATA BEGIN OF ls_order_item_data.
INCLUDE TYPE zcl_zexpand_emp_det_02_mpc=>ts_zemp_header_details.
DATA:    zemp_itemset TYPE  zcl_zexpand_emp_det_02_mpc=>tt_zemp_item,
END OF ls_order_item_data.

*********** Entity Set – HeaderSet ***********

CASE iv_entity_set_name.
WHEN 'ZEMP_HEADER_DETAILSSet'.

DATA(ls_key_tab=  it_key_tab[ name 'EmpId' ].
IF sy-subrc 0.
DATA(lemp_idls_key_tab-value.
ENDIF.

SELECT SINGLE FROM zemp_head  INTO @DATA(ls_headerdataWHERE emp_id @lemp_id.
SELECT FROM  zemp_item1  INTO TABLE @DATA(lt_itemdataWHERE emp_id @lemp_id.
MOVE-CORRESPONDING ls_headerdata TO ls_order_item_data.
ls_order_item_data-emp_id '1000'.

************ fill er_entity **********

MOVE-CORRESPONDING lt_itemdata  TO ls_order_item_data-zemp_itemset.
ls_order_item_data-zemp_itemset[ ]-age '22'.
copy_data_to_refEXPORTING is_data ls_order_item_data
CHANGING  cr_data er_entity ).

ENDCASE.
ENDMETHOD.

 

Implemented GET_EXPANDED_ENTITYSET method.


Method: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET.


 



 

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entityset.

*********** Structure ************
DATA BEGIN OF ls_order_item_data.
INCLUDE         TYPE zcl_zexpand_emp_det_02_mpc=>ts_zemp_header_details.
DATA:     zemp_itemset TYPE zcl_zexpand_emp_det_02_mpc=>tt_zemp_item,
END OF ls_order_item_data.
DATAlt_order_item_data LIKE TABLE OF ls_order_item_data.

*********** Entity Set – HeaderSet ***********
CASE iv_entity_set_name.
WHEN 'ZEMP_HEADER_DETAILSSet'.
SELECT  FROM zemp_head  INTO TABLE @DATA(lt_header).
SELECT  FROM  zemp_item1  INTO TABLE  @DATA(lt_item).
IF sy-subrc EQ 0.

************* Data processing logic *********
LOOP AT lt_header INTO DATA(ls_header).
MOVE-CORRESPONDING ls_header TO ls_order_item_data.
LOOP AT lt_item INTO DATA(ls_itemWHERE emp_id ls_header-emp_id.
MOVE-CORRESPONDING ls_item  TO ls_order_item_data.
APPEND  ls_item TO ls_order_item_data-zemp_itemset.
CLEAR ls_item.
ENDLOOP.
APPEND ls_order_item_data TO lt_order_item_data.
CLEAR ls_order_item_data.
ENDLOOP.
ENDIF.
DATA(lv_techname'EMPITEMSET'.
APPEND lv_techname TO et_expanded_tech_clauses.

************** Fill er_entityset ************

copy_data_to_refEXPORTING is_data lt_order_item_data
CHANGING  cr_data er_entityset ).
ENDCASE.
ENDMETHOD.

 

Step7:


 

Let's register service maintenance ,click on register service button

.



 



 

Click on ' Maintain Services'.

 



 

Click on ' Gateway Client '.



Metadata:

We have created the service and activated it. Now we can test using Gateway client (/IWFND/GW_CLIENT).

URI:' /sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/$metadata ' And execute.

 



 

OUTPUT :


Now we can test in gateway client (/IWFND/GW_CLIENT).Our service URL look like.

If you have observed the URL parameter $EXPAND ,you must have noticed that the path passed explains the hierarchy  form HEADER to ITEM with $EXPAND = ZEMP_HEADER_DETAILSSet TO ZEMP_ITEM SET.

This $EXPAND expression tells the framework to map multi level associated entity sets to the output result from the GET_EXPANDED_ENTITYSET method of the DPC.

In turn, the framework maps corresponding fields in the output result with the name same as the Navigation property of the entity sets.

 

 



 

URI: /sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet?$expand=ZEMP_ITEMSet&$format=json.

 



 

 

URI: /sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet?$expand=ZEMP_ITEMSet&$format=json.

{
"d" : {
"results" : [
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1000')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1000')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_HEADER_DETAILS"
},
"EmpId" "1000",
"EmpName" "Naveen",
"Dept" "SAP",
"ZEMP_ITEMSet" : {
"results" : [
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1000')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1000')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_ITEM"
},
"EmpId" "1000",
"Age" "00025",
"City" "HYD"
}
]
}
},
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1001')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1001')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_HEADER_DETAILS"
},
"EmpId" "1001",
"EmpName" "Ram",
"Dept" "SAP",
"ZEMP_ITEMSet" : {
"results" : [
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1001')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1001')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_ITEM"
},
"EmpId" "1001",
"Age" "00029",
"City" "HYD"
}
]
}
},
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1002')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1002')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_HEADER_DETAILS"
},
"EmpId" "1002",
"EmpName" "Sarath",
"Dept" "SAP",
"ZEMP_ITEMSet" : {
"results" : [
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1002')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1002')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_ITEM"
},
"EmpId" "1002",
"Age" "00035",
"City" "HYD"
}
]
}
},
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1003')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1003')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_HEADER_DETAILS"
},
"EmpId" "1003",
"EmpName" "Ashok",
"Dept" "SAP",
"ZEMP_ITEMSet" : {
"results" : [
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1003')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1003')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_ITEM"
},
"EmpId" "1003",
"Age" "00031",
"City" "HYD"
}
]
}
},
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1004')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1004')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_HEADER_DETAILS"
},
"EmpId" "1004",
"EmpName" "Naresh",
"Dept" "ABAP",
"ZEMP_ITEMSet" : {
"results" : [
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1004')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1004')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_ITEM"
},
"EmpId" "1004",
"Age" "00039",
"City" "HYD"
}
]
}
},
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1005')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_HEADER_DETAILSSet('1005')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_HEADER_DETAILS"
},
"EmpId" "1005",
"EmpName" "Krishna",
"Dept" "ABAP",
"ZEMP_ITEMSet" : {
"results" : [
{
"__metadata" : {
"id" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1005')",
"uri" "http://BISERVER:8009/sap/opu/odata/sap/ZEXPAND_EMP_DETAILS_SRV_02/ZEMP_ITEMSet('1005')",
"type" "ZEXPAND_EMP_DETAILS_SRV_02.ZEMP_ITEM"
},
"EmpId" "1005",
"Age" "00038",
"City" "HYD"
}
]
}
}
]
}

 

Conclusion: 

Important points to be considered while coding for association/navigation and data provider$expand,

Use of navigation path and navigation key, entities can be directly accessed or Via navigation property . code for both scenario using navigation path and navigation keys.

Whether framework expand or data provider expand provides better result will depends on your scenario .

I hope you enjoyed reading this blog and now will be able to play with association/navigation and $expand.

Please feel free if you have any different thoughts to improve any section of this blog post.

 

Thanks.

Appreciate your suggestion and comments.
2 Comments
Labels in this area