Technical Articles
Odata – Complex operations with multilevel expanded entityset and Multiple entries using batch
In this blog post, You will learn about different complex operations in Odata.
Lets start with a basic operation.
Get entity set
Create a SE11 structure
Go to SEGW
Click the data mode – > Import -> DDIC structure
Get entity set
Fill the necessary fields in the next screen in the wizard
In the runtime artifacts, go to DPC_EXT class
In the Inherited method,
Choose the required method (*GET_ENTITYSET) and redefine
Redefine generated get entity set method
Sample URL with filter
/sap/opu/odata/sap/<Technical service name>/<ENTITY SET>?&$filter=Land1 eq’ZA’
Below is the sample code for get entity set with filter
IF line_exists( it_filter_select_options[ property = 'Land1' ] ).
DATA(lr_range) = it_filter_select_options[ property = 'Land1' ]-select_options.
ENDIF.
SELECT a~taxtype,
b~text
FROM tfktaxnumtype_c AS a
LEFT OUTER JOIN tfktaxnumtype_t AS b
ON a~taxtype EQ b~taxtype
AND b~spras EQ @sy-langu
INTO CORRESPONDING FIELDS OF TABLE @et_entityset
WHERE a~taxtype IN @lr_range.
Create DEEP entity
Example: 1 parent row and multiple child rows
Create parent
Parent entity
Create child entity
Child entity
Create association
Association
Create navigation from parent entity
Navigation
For easy reference, give same name for navigation and ABAP fieldname
Now redefine /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY method in DPC_EXT
And use the below code to extract data
io_data_provider->read_entry_data( IMPORTING es_data = ls_supplier_data ).
Nested structure should be in below format
Structure of ls_supplier_data
types:
BEGIN OF ty_s_supplier .
INCLUDE TYPE zcl***mpc=>ts_vendorcreate.
TYPES: tax TYPE STANDARD TABLE OF zcl***mpc=>ts_tax WITH KEY taxtype.
TYPES: attachments_v TYPE STANDARD TABLE OF zcl***mpc=>ts_attachments_v WITH KEY usmd_title,
END OF ty_s_supplier .
Testing:
Before testing, first implement /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITY.
Just write one line code like this.
GET_EXPANDED_ENTITY
URL
/sap/opu/odata/sap/<TECHNICAL SERVICE NAME>/VENDORCREATESet(‘1234’)?$expand=VENDOR_TAX,VENDOR_ATTACHMENTS_V
Execute
Fill er_entity in debugger to get the payload structure
Fill entry in Debugger
Now click use as request
Click use as request
Now choose post
Change URI
Execute
Now create deep entity will be called
CREATE DEEP ENTITY
Post
Get Expanded Entity
Follow the same steps as create deep.
URL
/sap/opu/odata/sap/<TECHNICAL SERVICE NAME>/VENDORCREATESet(‘1234’)?$expand=VENDOR_TAX,VENDOR_ATTACHMENTS_V
Redefine the below method
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITY.
Fill the entries in exporting parameter er_entity
Get multilevel deep entity
Create different entities separately
Different entities
And bind them together by navigation at each level like above
Redefine /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET
In this method, fill the nested structure ty_s_tree
declare it like below
types:
BEGIN OF ty_s_l4_tree.
INCLUDE TYPE zcl_zmdg_mm_creq_prodh_mpc=>ts_l4_tree.
TYPES: l4_l5 TYPE STANDARD TABLE OF zcl_zmdg_mm_creq_prodh_mpc=>ts_l5_tree WITH DEFAULT KEY,
END OF ty_s_l4_tree .
types:
BEGIN OF ty_s_l3_tree.
INCLUDE TYPE zcl_zmdg_mm_creq_prodh_mpc=>ts_l3_tree.
TYPES: l3_l4 TYPE STANDARD TABLE OF ty_s_l4_tree WITH DEFAULT KEY,
END OF ty_s_l3_tree .
types:
BEGIN OF ty_s_l2_tree.
INCLUDE TYPE zcl_zmdg_mm_creq_prodh_mpc=>ts_l2_tree.
TYPES: l2_l3 TYPE STANDARD TABLE OF ty_s_l3_tree WITH DEFAULT KEY,
END OF ty_s_l2_tree .
types:
BEGIN OF ty_s_tree.
INCLUDE TYPE zcl_zmdg_mm_creq_prodh_mpc=>ts_l1_tree.
TYPES: l1_l2 TYPE STANDARD TABLE OF ty_s_l2_tree WITH DEFAULT KEY,
END OF ty_s_tree .
Testing:
URL
Choose the first entityset and in expand, give the navigation
/sap/opu/odata/sap/<TECHNICAL SERVICE NAME>/L1_TREESet?$expand=L1_L2/L2_L3/L3_L4/L4_L5&$format=json
Result of multilevel deep structure
Batch Update for table – Multiple entries
Redefine the below methods
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN
METHOD /iwbep/if_mgw_appl_srv_runtime~changeset_begin.
cv_defer_mode = abap_true.
ENDMETHOD.
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END
Just implement it, nothing to write.
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_PROCESS
METHOD /iwbep/if_mgw_appl_srv_runtime~changeset_process.
LOOP AT it_changeset_request INTO DATA(ls_request) WHERE operation_type = 'CE'.
lo_create_context ?= ls_request-request_context.
lv_entity_type = lo_create_context->get_entity_type_name( ).
IF lv_entity_type = 'CREATE_PRODH'.
ls_request-entry_provider->read_entry_data( IMPORTING es_data = ls_data ).
IF ls_data IS NOT INITIAL.
*
Required logic
*
copy_data_to_ref(
EXPORTING
is_data = ls_data
CHANGING
cr_data = ls_changeset_response-entity_data ).
ls_changeset_response-operation_no = ls_request-operation_no.
INSERT ls_changeset_response INTO TABLE ct_changeset_response.
ENDIF.
ELSE.
* entity alredy exists - $batch will be rolled back
ls_message-msgty = 'E'.
ls_message-msgid = 'ZMDG_MM_LEAN'.
ls_message-msgno = '001'.
ls_message-msgv1 = ls_data-prodh.
me->/iwbep/if_mgw_conv_srv_runtime~get_message_container( )->add_message(
iv_msg_type = ls_message-msgty
iv_msg_id = ls_message-msgid
iv_msg_number = ls_message-msgno
iv_msg_v1 = ls_message-msgv1
iv_msg_v2 = ls_message-msgv2
iv_msg_v3 = ls_message-msgv3
iv_msg_v4 = ls_message-msgv4
).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = me->/iwbep/if_mgw_conv_srv_runtime~get_message_container( ).
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.
Testing
Give below URI
Click add uri option and choose $batch and automatically the HTTP method moves to post operation
and HTTP request is filled with default code.
Batch update
Replace the code like below if there are multiple entries
NOTE: Each entry should have unique Changeset name like changeset1,changeset2 etc..
And be cautious about the unnecessary spaces and indentation.
--batch
Content-Type: multipart/mixed; boundary=changeset1
--changeset1
Content-Type: application/http
Content-Transfer-Encoding: binary
POST CREATE_PRODHSet HTTP/1.1
Content-Type: application/json
{
"Field1" : "30002",
"Field2" : "Value",
}
--changeset1--
--batch
Content-Type: multipart/mixed; boundary=changeset2
--changeset2
Content-Type: application/http
Content-Transfer-Encoding: binary
POST CREATE_PRODHSet HTTP/1.1
Content-Type: application/json
{
"Field1" : "30004",
"Field2" : "Value",
}
--changeset2--
--batch--
Now you must have learnt about the tweaks required for most commonly performed operations in Odata.
I hope this post will help you when you get stuck or come across this kind of requirement.
Please let me know your thoughts on the comment section.
For other Odata related queries, reach out to this tag.
https://answers.sap.com/tags.html
🙂
Hi Aravindh! Thank you for sharing.
What you describe is a valid approach but I feel we need to disclose that SEGW is not the only way to create OData services these days and, depending on the ABAP / NW version the reader is using, better alternatives exist. Before jumping to implementing what is described, I'd encourage the readers to find out what is the suitable development model for their version and specific use case.
I've made a comment about this on a similar blog, please take a look:
https://blogs.sap.com/2021/05/19/a-step-by-step-process-to-post-odata-services-in-sap-sap-hana-system/comment-page-1/#comment-587808
Thank you.
Sure. Thanks Jelena!
This has been really useful. A quick question though! I am getting the expand working fine but I want to add some filters. In the url
'/sap/opu/odata/sap/<TECHNICAL SERVICE NAME>/L1_TREESet?$expand=L1_L2/L2_L3/L3_L4/L4_L5&$format=json'
if I wanted to filter on elements on L2_L3 and L3_L4 is there a way of doing that ??