SAP oData Service [POST]: Multiple Table Input
Overview
- In this blog, we will come to know, how we can post multiple table input to oData Service
- that is nothing but a case of single header table and multiple-item table input to oData Service and receiving output in 3rd table structure.
- This method is also called as ‘oData Create method‘ where in a singe request, we input multiple ‘Entity Set’ structural data (tables).
- This blogs is a business case example of parent blog:
Business Scenario:
- Creating a purchase order via fiori app.
- In this case, in back-end System, we create a RFC which can accept Single Header and multiple line item table input (as a request parameters), do the purchase order creation based on input and return creation status in a output table (as a response parameter).
- We consume this RFC in oData Service in such a manner, so that oData Service can accept single header and multiple item table as a request (input) and in response it can return output table data of RFC.
- Here, below explained steps is synonym to above business scenario.
Deep Insert in SAP OData service
- To post/push Header and line items together to the back-end RFC via oData Service, we follow Create_Deep_Entity approach.
- The ‘Create_Deep_Entity’ approach is also called as Deep Insert in SAP OData service
- Deep insert is used to POST the nested structure of feed/collections to the back-end system.
- By implementing this we can reduce the no.of OData calls made to the SAP Netweaver Gateway server.
- Entity sets (Header, Item and Result) which are used should be associated, means while calling one Entity set (for e.g. say Header), we should use Item and Result Entity Sets as well, thus in a single call we are using three Entity Sets thus avoiding no.of OData calls.
- This can be achieved by the concept of Association and Navigation properties.
Association and Navigation properties
- These are two important properties available in SAP Netweaver Gateway to associate two entity types.
- In our business example (i.e. to create Purchase Order), back-end RFC has three tables, two table (Header and Item) as a input and one table (Result) as a output.
- Parallel, we also create three Entity Sets in oData with respective properties (i.e. as of similar RFC table structures will all fields/elements/columns),
- Header Set (for header level input, only single record)
- Item Set (for item level input, can be multiple record)
- Result Set (to capture output, single record)
- These above entity types are individual and can be executed differently.
- But here we want to push Header and Items data at a time in one call and in acknowledgement we want output in Result entity. This is can be achieved using association and navigation property
Steps:
Rfc Details
- For reference purpose only, with help of below RFC screen of back-end system, input / output structures can be understood:
- RFC’s input tables are ‘TBL_HEADER’ and ‘TBL_ITEM’
- and RFC’s output table is ‘TBL_RESULT’.
- Parallel structures we create in oData Service as Entity Sets.
oData Service Details:
- To post/push Header and line items together to the back-end RFC via oData Service using ‘Create_Deep_Entity’ approach, following steps can be followed:
- In Fiori-Server, go to Service Builder t-code ‘SEGW’ and expand the service to create Entities.
- Here, we will create three Entity Sets:
- Two for handling request in oData Service
- Entity ‘Header’ to capture Header input
- Entity ‘Item’ to capture Item level input
- and One for response from oData Service
- Entity ‘Result’ to capture output returned from back-end RFC
- Two for handling request in oData Service
- In a single call via one Entity Set (HeaderSet) URI, we will pass inputs using 1st & 2nd Entity Sets (Header & Item) and retrieve output in 3rd Entity Set (Result). This will be achieved by concept of Associations and Navigation.
[1] For header level input, create a ‘Header’ Entity
- This is meta structure for ‘Header’ level request data. It will be one set per request.
- Create Properties and save/re-generate OData Service. In this Entity, we create three properties (equivalent to Table columns of RFC) and checking one as key property.
[2] For item level input, create a ‘Item’ Entity
- This is meta structure for ‘Item’ level request data. It can be one or multiple sets per request.
- Create Properties and save/re-generate OData Service. In this Entity, we create three properties (equivalent to Table columns of RFC) and checking one as key property.
[3] To capture output, create a ‘Result’ Entity
- This is meta structure for holding output during service response. It will be one per service call.
- Create Properties and save/re-generate OData Service. In this Entity, we create two properties (equivalent to Table columns of RFC) and checking one as key property.
- Thus, we have a odata meta structure as below:
- which is parallel to below back-end RFC’s table structures
[4] Creating Associations & Navigaions
- If, we want in one oData service call, to post both (Header/Item Entity) request and to get output in 3rd Entity (i.e. Result), this is can be achieved using association and navigation property.
- Go to oData Service project in t-code ‘SEGW’ -> select ‘Associations’ -> right click -> ‘Create’
- Here we create two association & Navigation:
- [A] Association & Navigation between Header and Item Entity
- This is required when we want to post both Entity Set input (Header and Item) on call of ‘Header’ Entity Set.
- Association Name: HEADER_ITEM
- Navigation Name: ItemSet
- Creation steps can be refereed as below:
- While Creating Associations, in next window, enter below details
- Principal Entity – To which you want to build the association
- Dependent Entity – From which you want to get the data based on association
- Cardinality – What the occurrence of no records
- Navigation Property– Name of the navigation property for the Entity Type
- In the next windows, provide the common field among two entity sets (Header and Item) and click on Next
- In next window. verify the entries and Click on Finish.
- This creates a navigation and association property for “Header” Entity Type.
- Thus, we can understand that ‘Item’ entity is associated to ‘Header’ Entity.
- Check/Verify Navigations:
- Thus, when we call ‘Header’ Entity set, it will also navigate to ‘Item’ entity, means while calling entity set ‘Header’ , we will get meta structure access of ‘Item’ entity set too.
- [B] Association & Navigation between Header and Item Entity
- This is required when we want to get output in 3rd Entity Set ‘Result’ on call of 1st ‘Header’ Entity Set.
- Association Name: HEADER_RESULT
- Navigation Name: NAVRESULT
- Creation steps can be refereed as below:
- Enter details in next window i.e. Entity info related to ‘Header’ and ‘Result’, here give Navigation Property name as ‘NAVRESULT‘
- Click next, here select one field (MSG1) from ‘Result’ entity
- Click Next, here Association and respective Entity Sets info can be seen.
- Click finish. and verify the Association details
- and verify Navigation details too, post that save and re-run ‘Generate Runtime object’ of project.
[5] Re-definitions in MPC & DPC of oData
- MPC (Model Provider class) – This is used to define model. we can use the method Define to create entity, properties etc using code based implementation. we rarely use MPC extension class.
- DPC (Data provider class) – used to code our ‘CRUDQ’ methods as well as function import methods. we write all our logic in redefined methods of DPC extension class.
- The ‘CRUDQ’ methods:
- This is nothing but Create, Read, Update, Delete and Query operations which we can do in oData Service.
- This blog’s example is of ‘Create’ operation in oData Service.
[5.1] Re-define MPC
- Go to oData Service project in t-code ‘SEGW’ -> Runtime Artifacts -> select and double click on oData’s ‘_MPC_EXT’ as shown in below screen
- In next window of oData’s ‘_MPC_EXT’, select class folder ‘ZCL_ZTEST_ODATA_MPC_EXT’
- Double click on it.
- Edit code and here define custom data Type ‘TS_DEEP_ENTITY‘ after PUBLIC SECTION.
- This type is required to club all three (Header/Item/Result) Entity Set structure to single structure.
- Here, for structure creation of Entity ‘Item’ and ‘Result’, variable names should be same as of ‘Navigation Property‘ name created in Entity ‘Header’ else structure can not be referred in code. Below Screen of Navigation definition can be seen for reference
- Custom data Type ‘TS_DEEP_ENTITY‘ has reference of all three structures (Header/Item and Result).
- For Entity ‘Header’: FIELD1, FIELD12, FIELD13
- For Entity ‘Item’: ItemSet (same name as of ‘Navigation Property‘)
- For Entity ‘Result’: NAVRESULT (same name as of ‘Navigation Property‘)
-
class ZCL_ZTEST_ODATA_MPC_EXT definition public inheriting from ZCL_ZTEST_ODATA_MPC create public . public section. types: BEGIN OF TS_DEEP_ENTITY, FIELD1 TYPE STRING, FIELD2 TYPE STRING, FIELD3 TYPE STRING, ItemSet TYPE STANDARD TABLE OF TS_ITEM WITH DEFAULT KEY, "var name should be same as of navigation property name NAVRESULT TYPE STANDARD TABLE OF TS_RESULT WITH DEFAULT KEY, "var name should be same as of navigation property name END OF TS_DEEP_ENTITY . methods DEFINE redefinition .
- Save and activate
- Now next is to refine ‘DEFINE‘ METHOD. For same goto folder ‘Methods’ -> ‘Inherited Method’ -> ‘DEFINE’ -> right click -> select ‘Redefine’
- Write below code in ‘DEFINE’ method:
-
DATA: lo_annotation TYPE REF TO /iwbep/if_mgw_odata_annotation, lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_entity_typ, lo_complex_type TYPE REF TO /iwbep/if_mgw_odata_cmplx_type, lo_property TYPE REF TO /iwbep/if_mgw_odata_property, lo_entity_set TYPE REF TO /iwbep/if_mgw_odata_entity_set. super->define( ). lo_entity_type = model->get_entity_type( iv_entity_name = 'Header' ). lo_entity_type->bind_structure( iv_structure_name = 'ZCL_ZTEST_ODATA_MPC_EXT=>TS_DEEP_ENTITY' ).
- save and activate.
[5.2] Re-define DPC
- Now Go to ZCL_ZTEST_ODATA_DPC_EXT
- double click
- Here we need to work in two methods
- [1] CREATE_DEEP_ENTITY (need to re-define)
- [2] CUSTOME_CREATE_DEEP_ENTITY (need to create)
- Steps to Re-define method ‘CREATE_DEEP_ENTITY’:
- to Redefine the method ‘CREATE_DEEP_ENTITY’
- Go to project’s ‘_DPC_EXT’ -> folder ‘Methods’ -> folder ‘Inherited Methods’ -> select folder /IWBEP/IF_MGW_APPL_SRV_RUNTIME -> select ‘CREATE_DEEP_ENTITY’
- right click -> ReDefine
- Post redefinetion, it can be seen as /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY
- double click on it -> Edit it
- and write below code in CREATE_DEEP_ENTITY to define deep entity
-
method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY. DATA: IR_DEEP_ENTITY TYPE ZCL_ZTEST_ODATA_MPC_EXT=>TS_DEEP_ENTITY. CASE iv_entity_set_name. *-------------------------------------------------------------------------* * When EntitySet 'HeaderSet' is been invoked via service Url *-------------------------------------------------------------------------* WHEN 'HeaderSet'. CALL METHOD me->custome_create_deep_entity EXPORTING IV_ENTITY_NAME = iv_entity_name IV_ENTITY_SET_NAME = iv_entity_set_name IV_SOURCE_NAME = iv_source_name IT_KEY_TAB = it_key_tab IT_NAVIGATION_PATH = it_navigation_path IO_EXPAND = IO_EXPAND IO_TECH_REQUEST_CONTEXT = io_tech_request_context IO_DATA_PROVIDER = io_data_provider IMPORTING ER_DEEP_ENTITY = IR_DEEP_ENTITY . copy_data_to_ref( EXPORTING is_data = IR_DEEP_ENTITY CHANGING cr_data = er_deep_entity ). ENDCASE. endmethod.
- save and activate.
- Steps to Create method ‘CUSTOME_CREATE_DEEP_ENTITY’
- In ‘_DPC_EXT’ -> Go to folder ‘Methods’ -> Enter new method name ‘CUSTOME_CREATE_DEEP_ENTITY‘ in center column as shown in below screen
- To define parameter, click on “Parameter” button
-
'PARAMETER LIST: IV_ENTITY_NAME Importing Type STRING IV_ENTITY_SET_NAME Importing Type STRING IV_SOURCE_NAME Importing Type STRING IT_KEY_TAB Importing Type /IWBEP/T_MGW_NAME_VALUE_PAIR IT_NAVIGATION_PATH Importing Type /IWBEP/T_MGW_NAVIGATION_PATH IO_EXPAND Importing Type Ref To /IWBEP/IF_MGW_ODATA_EXPAND IO_TECH_REQUEST_CONTEXT Importing Type Ref To /IWBEP/IF_MGW_REQ_ENTITY_C IO_DATA_PROVIDER Importing Type Ref To /IWBEP/IF_MGW_ENTRY_PROVIDER ER_DEEP_ENTITY Exporting Type ZCL_ZTEST_ODATA_MPC_EXT=>TS_DEEP_ENTITY
- Note: ‘ER_DEEP_ENTITY‘ is EXPORTING parameter
- To define exception, click on “Exception” button
-
/IWBEP/CX_MGW_BUSI_EXCEPTION /IWBEP/CX_MGW_TECH_EXCEPTION
- Save and Activate.
- Next write code in method ‘Custome_Create Deep Entity’
-
method CUSTOME_CREATE_DEEP_ENTITY. Types: begin of TYP_HEADER, FLD_1 type C length 4, FLD_2 type C length 4, FLD_3 type C length 10, end of TYP_HEADER . Types: begin of TYP_ITEM, IFLD_1 type C length 4, IFLD_2 type C length 4, IFLD_3 type C length 10, end of TYP_ITEM . Types: begin of TYP_RESULT, MSG_1 type STRING, MSG_2 type STRING, end of TYP_RESULT . DATA: IR_DEEP_ENTITY TYPE ZCL_ZTEST_ODATA_MPC_EXT=>TS_DEEP_ENTITY, IT_RFC_HEADER TYPE STANDARD TABLE OF TYP_HEADER, WA_RFC_HEADER TYPE TYP_HEADER, IT_RFC_ITEM TYPE TABLE OF TYP_ITEM, WA_RFC_ITEM TYPE TYP_ITEM, IT_RFC_RESULT TYPE STANDARD TABLE OF TYP_RESULT, WA_RFC_RESULT TYPE TYP_RESULT, WA_RESULTSET TYPE ZCL_ZTEST_ODATA_MPC_EXT=>TS_RESULT, WA_ITEM TYPE ZCL_ZTEST_ODATA_MPC_EXT=>TS_ITEM. FIELD-SYMBOLS: <WA_ITEM> TYPE ZCL_ZTEST_ODATA_MPC_EXT=>TS_ITEM. FIELD-SYMBOLS: <WA_RESULT> TYPE ZCL_ZTEST_ODATA_MPC_EXT=>TS_RESULT. *Transform INPUT REQUEST FROM ODATA-SERVICE into the internal structure io_data_provider->read_entry_data( IMPORTING es_data = IR_DEEP_ENTITY ). * extract Header details from Entity 'Header' WA_RFC_HEADER-FLD_1 = IR_DEEP_ENTITY-FIELD1. WA_RFC_HEADER-FLD_2 = IR_DEEP_ENTITY-FIELD2. WA_RFC_HEADER-FLD_3 = IR_DEEP_ENTITY-FIELD3. APPEND WA_RFC_HEADER TO IT_RFC_HEADER. Clear WA_RFC_HEADER. * extract Item details from Entity 'Item' (tabulabr input fields) LOOP AT IR_DEEP_ENTITY-ItemSet ASSIGNING <WA_ITEM>. WA_RFC_ITEM-IFLD_1 = <WA_ITEM>-IFLD1. WA_RFC_ITEM-IFLD_2 = <WA_ITEM>-IFLD2. WA_RFC_ITEM-IFLD_3 = <WA_ITEM>-IFLD3. APPEND WA_RFC_ITEM TO IT_RFC_ITEM. CLEAR WA_RFC_ITEM. ENDLOOP. * Calling SAP R3's RFC via RFCDestination Call FUNCTION 'ZTEST_RFC_FIORI' DESTINATION '<RfcDestinationName of BackendSystem>' TABLES TBL_HEADER = IT_RFC_HEADER TBL_ITEM = IT_RFC_ITEM TBL_RESULT = IT_RFC_RESULT. *EXPORTING OUTPUT TO oData EntitySet 'ResultSet' LOOP AT IT_RFC_RESULT INTO WA_RFC_RESULT. "Return output into Entity 'RESULT' via 'NavigationProperty=NAVRESULT' WA_RESULTSET-MSG1 = WA_RFC_RESULT-MSG_1. WA_RESULTSET-MSG2 = WA_RFC_RESULT-MSG_2. APPEND WA_RESULTSET TO ER_DEEP_ENTITY-NAVRESULT. CLEAR WA_RESULTSET. ENDLOOP. COMMIT WORK. endmethod.
- Save and activate.
Testing the oData Service:
[1] Testing in Fiori-Server using t-code ‘/n/iwfnd/gw_client’:
- [A] Check meta structure [GET Method]:
- URL: ‘/sap/opu/odata/sap/ZTEST_ODATA_SRV/$metadata’
- [B] Multiple Entity Request [POST Method]:
- As we know oData Service supports both JSON as well XML formats.
- First lets test using XML format
- Here we try to POST single header and multiple-item table to oData Service
- i.e. posting one ‘Header’ Entity Data and multiple ‘Item’ Entity Data. This type of request should be framed in following XML format.
- Request-XML format:
-
<?xml version="1.0" encoding="UTF-8"?> <atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <atom:content type="application/xml"> <m:properties> <d:Field1>hvl1</d:Field1> <d:Field2>hvl2</d:Field2> <d:Field3>hvl3</d:Field3> </m:properties> </atom:content> <atom:link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ItemSet" type="application/atom+xml;type=feed" title="ZTEST_ODATA_SRV.HEADER_ITEM"> <m:inline> <atom:feed> <atom:entry> <atom:content type="application/xml"> <m:properties> <!--<d:Row>1</d:Row>--> <d:IFLD1>rv11</d:IFLD1> <d:IFLD2>rv12</d:IFLD2> <d:IFLD3>rv13</d:IFLD3> </m:properties> </atom:content> </atom:entry> <atom:entry> <atom:content type="application/xml"> <m:properties> <!--<d:Row>2</d:Row>--> <d:IFLD1>rv21</d:IFLD1> <d:IFLD2>rv22</d:IFLD2> <d:IFLD3>rv23</d:IFLD3> </m:properties> </atom:content> </atom:entry> </atom:feed> </m:inline> </atom:link> <atom:link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/NAVRESULT" type="application/atom+xml;type=feed" title="ZTEST_ODATA_SRV.HEADER_RESULT"> <m:inline> <atom:feed> <atom:entry> <atom:content type="application/xml"> <m:properties> <!--<d:Row>1</d:Row>--> <d:MSG1></d:MSG1> <d:MSG2></d:MSG2> </m:properties> </atom:content> </atom:entry> </atom:feed> </m:inline> </atom:link> </atom:entry>
- In JSON-Format, above request structure will look like as below:
-
{ "Field1": "hvl1", "Field2": "hvl2", "Field3": "hvl3", "ItemSet": [ { "IFLD1": "rv11", "IFLD2": "rv12", "IFLD3": "rv13" }, { "IFLD1": "rv21", "IFLD2": "rv22", "IFLD3": "rv23" } ], "NAVRESULT": [ { "MSG1": "", "MSG2": "" } ] }
-
- if we see above request XML, we are passing inputs as below:
- Entity ‘Header’: At header level one row input (Field1,Field2,Field3)
- Entity ‘Item’: At Item level two row input (ItemSet)
- Entity ‘Result’: one blank row, this is required to get output (NAVRESULT)
- POST above request to Entity set of ‘Header’ from fiori t-code ‘/n/iwfnd/gw_client‘ using below details:
- if we see above request XML, we are passing inputs as below:
-
URL: /sap/opu/odata/sap/ZTEST_ODATA_SRV/HeaderSet Method: POST In above Request-XML payload, below details been used: [1] For Request (input of Two Entity 'Header' and 'Item') Associations: "ZTEST_ODATA_SRV.HEADER_ITEM" Navigation: "http://schemas.microsoft.com/ado/2007/08/dataservices/related/ItemSet" [2] For Response (output in Enity 'Result') Associations: "ZTEST_ODATA_SRV.HEADER_ITEM" Navigation: "http://schemas.microsoft.com/ado/2007/08/dataservices/related/NAVRESULT"
- The oData Service Request Screen in Fiori’s t-code ‘/n/iwfnd/GW_Client’
- The oData Service Response received as below:
- Below xml output received where we can see Entity Set ‘ResultSet’ has output
-
<?xml version="1.0" encoding="utf-8"?> <entry xml:base="http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"> <id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/HeaderSet('')</id> <title type="text">HeaderSet('')</title> <updated>2018-03-29T11:04:19Z</updated> <category term="ZTEST_ODATA_SRV.Header" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/> <link href="HeaderSet('')" rel="self" title="Header"/> <link href="HeaderSet('')/ItemSet" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ItemSet" type="application/atom+xml;type=feed" title="ItemSet"> <m:inline/> </link> <link href="HeaderSet('')/NAVRESULT" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/NAVRESULT" type="application/atom+xml;type=feed" title="NAVRESULT"> <m:inline> <feed xml:base="http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/"> <id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/HeaderSet('')/NAVRESULT</id> <title type="text">ResultSet</title> <updated>2018-03-29T11:04:19Z</updated> <author> <name/> </author> <link href="HeaderSet('')/NAVRESULT" rel="self" title="ResultSet"/> <entry> <id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/ResultSet('hvl1')</id> <title type="text">ResultSet('hvl1')</title> <updated>2018-03-29T11:04:19Z</updated> <category term="ZTEST_ODATA_SRV.Result" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/> <link href="ResultSet('hvl1')" rel="self" title="Result"/> <content type="application/xml"> <m:properties> <d:MSG1>hvl1</d:MSG1> <d:MSG2>Data Receievd</d:MSG2> </m:properties> </content> </entry> </feed> </m:inline> </link> <content type="application/xml"> <m:properties> <d:Field1/> <d:Field2/> <d:Field3/> </m:properties> </content> </entry>
- Debugging-Screen to understand how input and output is flowing:
- [a] Input from oData Service request-Xml payload
- Structure ‘IR_DEEP_ENTITY’
- Structure ‘IR_DEEP_ENTITY’ -> ITEMSET (which is Item level input)
- Structure ‘IR_DEEP_ENTITY’ -> NAVRESULT (which is blank)
- [b] Back-end RFC call
- Above two table input will be provided to RFC, post RFC call, it returns output in new table which will be mapped to Entity Set ‘Result’
- [c] Returning output of RFC table to oData Service as a response
- Out from RFC received in table ‘IT_RFC_RESULT’
- Data of table ‘IT_RFC_RESULT’ is been mapped to ‘ER_DEEP_ENTITY-NAVRESULT’ which is oData Service’s Entity Set ‘RESULT’ strcture reference
[2] Testing in Fiori-App using Eclipse:
- Please refer below blog to consume/call this oData Service in Fiori-App using Eclipse
Great job,nice blog.
I added to my library. 🙂
Congratulations.
Another nice step by step. You might want to link it to your other blog!
Michelle
Dear Michelle Crapo,
Thanks, next coming soon "SAP oData Get: Multiple Table Output", keep checking.
Thanks & Regards
Dilip
Perfect - I'll be reading that one too!
Michelle
HI Dilip Kumar KrishnaDeo Pandey,
Nice blog, I have a question for you. As I can see you have implemented Define Method of MPC class. Could you pls let me know the reason.
Hi suman kumar,
Please find following comments w.r.t. your query, for more clarity:
Thanks & Regards,
Dilip
Hi ,
What Should be done if the input and output both have simultaneous multiple table input?
Thanks in advance.
Hi Dubra,
Regards,
Dilip
Hi,
can you share the example where both input and output have multiple tables.
Thanks in advance
Dear Rini,
At this moment, I do not have any ready example for "both input and output have multiple tables".
But you can use below blog's references for this case:
Sorry for the delay in reply
Thanks & Regards,
Dilip Pandey
Hi Dilip,
Could we use the [POST]: Multiple Table Input to read table entries ?
If yes, should we also implement the method ‘CUSTOME_CREATE_DEEP_ENTITY’ to enhance the read logic other than create entries in the table?
If no, should we use $batch to read response table for different fields requests?
If any concern, please feel free to let me know.
Thanks and regards,
Sophie
Hi Sophie,
Sorry for late reply..
To read table entries, please refer below blog:
SAP oData Service [GET]: Multiple Table Output
Thanks & Reagrds,
Dilip
Hi Dilip,
Is it possible to get the output in json ? currently the code provides output in xml .
Thanks
Govind
Hi Govind,
Yes, it is possible to get output in JSON. OData-Services support both content-types (i.e. XML and JSON).
You have to add two headers as shown in below screens:
(Test using T-Code: /n/iwfnd/GW_CLIENT)
As a further reference, same service's output in xml format is as shown in below screen:
Thanks & Regards,
Dilip
Dilip,
Thanks for the help, it works after adding adding header : accept = application/json. Earlier I was just giving Content-Type = application/json and was returning xml output.
One more quick question : Is it possible generate 2 sets of output based on certain condition or certain User Input ( making a use case based on the example you provided) as below:
Basically trying to return different output structure/tables based on certain input parameters .
Thanks
Govind
Hi Govind,
Yes, its possible to get multiple output tables based on certain input parameters, please refer below blog for same:
SAP oData Service [GET]: Multiple Table Output
Thanks & Regards,
Dilip
Thanks Dilip, this really helped shaping my requirement.
I was able to generate the url but not able to call the endpoint via postman. Initially i was getting error related to CSRF token I disabled the option via sicf but after that when executing via GET method, I am getting Error message 'Error when processing resource'.
The metadata url working fine but when trying to fetch data I am getting error. Any helpful hints will be appreciated.
Thanks
Govind
Hi Govind,
In Fiori server, check t-code /n/iwfnd/error_log/, you should get something.
And at initial, always try to test your service using t-code /n/iwfnd/gw_client/, once everything is ok here then you can check from POSTMAN etc.
Thanks & Regards,
Dilip
Dilip,
The service works fine in /n/iwfnd/gw_client/ but when trying to access via python or postman with POST method we are getting 'Error when processing resource'.
This is because we haven't redefined required method in odata ?
Thanks
Govind
Hi Govind,
If service works fine in “/n/iwfnd/gw_client/” then everything should be ok.
Are you only testing meta structure inside that t-code ?
You should check service working in t-code “/n/iwfnd/gw_client/” as it is which you were trying to test via ‘POSTMAN’.
About ‘Error when processing resource’ via ‘POSTMAN’, plz get more details from log to get the root cause.
Thanks & Regards,
Dilip
Dilip,
Thanks for the reply.
Both metadata is working fine is /n/iwfnd/gw_client/ and outside SAP such as browser and postman. The entityset service is working fine in /n/iwfnd/gw_client/ but not is postman with POST method.
I have used the same example as above and activated following method in:
Data Model (looks as below):
HighLevelRecon
ReconciliationResult
Response
RequestStructure--- Navigation Properties
--- HighLevelRecon
--- ItemSet
--- ReturnMessages
Methods:
DPC_EXT -- > /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY
DPC_EXT -- >REQUESTSTRUCTURE_GET_ENTITYSET
DPC_EXT -- >CUSTOME_CREATE_DEEP_ENTITY ( Returns nested structure based on Json input as body)
Class / Methods:
MPC_EXT --> DEFINE
Thanks
Govind
Hi Govind,
If your service is working with POST method in t-code '/n/iwfnd/gw_client/'
then there is no issue with service, you can provide more details of 'POSTMAN' tool log for getting the root cause.
Thanks
Dilip
Hi Dilip Kumar KrishnaDeo Pandey
Thanks for the detailed information.
Regarding TS_DEEP_ENTITY structure creation in *_MPC_EXT class. It is clearing off when I do "Generate Runtime Objects" again.
How to avoid without clearing the TS_DEEP_ENTITY when I use "Generate Runtime Objects" again?
Thanks in advance.
Prabhakar
Hi Prabhakar,
Clearing off !!...is it like you are not able to save it ? No such error faced by me.
In '*_MPC_EXT', whenever you are defining 'TS_DEEP_ENTITY', save and activate the object then try 'Generate Runtime Objects'.
Regards,
Dilip
Hi Dilip,
Thanks for the reply.
Now I understood, how to define TS_DEEP_ENTITY structure under public section.
Actually earlier I have defined this structure by clicking on the existing types in Types tab. When I am defining the structure like this way, the structure TS_DEEP_ENTITY is clearing when I try 'Generate Runtime Objects'. Then I followed the below steps to define it.
_MPC_EXT -> Types tab -> Enter TS_DEEP_ENTITY visibility - PUBLIC -> click on Direct Type Entry -> now declare the header fields and item structures in TS_DEEP_ENTITY structure.
Again I tried 'Generate Runtime Objects' this time it doesn't clear. Then I understood earlier I have defined in the wrong place that's why it was cleared.
Thanks again.
Regards,
Prabhakar
Hi Dilip, Excellent Blog... really helped... Can you please let us know the Possibility to send multiple records in the Header Table. Lets us assume your example is to create Sales order header with multiple line items, In this example we can Post only one Sales Order with multiple line items, Can we send Multiple Sales document header and their respective Line items. Please provide input.
Thanks .
Hi Satish,
I got your query, but this blog will only entertain single Sales ORDER info (as per your example reference one header/multiple Item).
For multiple SalesOrder in a single call/post, I will check the possibility and let you know soon.
Thanks/Regards
Dilip
Excellent blog Dilip.
Question.
For POST with create deep entity, Is there any way to get the request xml structure for the front end/postman tool without implementing the get methods.
Thanks,
Prasad
Dear Prasad,
Your query's last part is little bit confusing, however, please find below comments which I've related:
[1] To get meta-structure of your service, respective below URL-pattern need to be called using GET method
/sap/opu/odata/sap/ZTEST_ODATA_SRV/$metadata
[2] And for POST method, you need to send 'request' on respective url-pattern, it can either be a 'xml structure' or a 'JSON' strcture, which syntax is given in blog, please refer. The same structure can be followed to test it from 'POSTMAN' tool as well on respective url.
Note: Above are the standard techniques to deal with different URL-Patterns of the service.
Thanks & Regards,
Dilip
hi Dilip,
such an amazing Blog. thank you.
i have one doubt. te test the service in the above example we used XML HTTP request.how to create this HTTP xml request template?
because for normal entity cretion we will implement first GET_ENTITY method ->use as request -> and then we will pass the test values to the template.
but in case of create_deep_entity how we will get the XML request template?
Hi Bala,
The xml request template example is given in the blog itself.
And same request template you deal in JSON format inside JScript.
For other supporting template w.r.t. oData-service URL pattern type, you can find online.
Thanks & Regards,
Dilip
Hi Dilip,
Nice job!
When I'm testing my service from /IWFND/GW_CLIENT I'm getting an error: Method 'ENTITYSET_CREATE_ENTITY' not implemented in data provider class. Where am I getting wrong?
BR,
Leonardo
Hi Leonardo,
If you are trying above blog case, pleas re-check all the steps again.
Check if you have re-defined /IWBEP/IF_MGW_APPL_SRV_RUNTIME -> select ‘CREATE_DEEP_ENTITY’
Thanks & Regards,
Dilip
Hi,
I've got this problem and in my case I wasn't informing all fields from navigation properties.
Maybe someone else got this problem as well.
So, inform all fields from main and children entities.
BR,
Danilo
Hi Dilip,
Thanks a lot for sharing this great content!
I am able to follow all the change but I have issue with the output HEADERSET() NAVRESULT. It somehow doesn't return the message from BAPI into XML. It only shows as follow
<link title="NavResult" type="application/atom+xml;type=feed" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/NavResult" href="HeaderSet('')/NavResult"/>
My suspicion is on ER_DEEP_ENTITY. It only being filled by message in structure NAVRESULT. Should we also fill the other field from header (FIELD1, FIELD2, FIELD3) and item (ITEMSET)?
Or is there anything else that may cause this error?
Thanks
Regards
Hadi
Dear Hadi Wijaya,
Please check below things and if possible re-check once all the steps:
Sorry for the delay in reply
Thanks & Regards,
Dilip Pandey
Hi Hadi,
can you solve your problem? I can´t get the message from the BAPI.
Hi Dilip,
Thanks for your sharing, really helpful.
But I have a question, May I use the same way for the get/put method?(I need return the header and item in one request)? Thanks.
Thanks & Regards
Andy
Dear Andy,
Sorry for very late reply, till now, you may have already addressed the requirement. If, so, please share your tips.
Till now, I have not tried any case with PUT operation.
Thanks & Regards,
Dilip
Hi Dilip, This swami here. I saw yours all posts which help people. I could not able to figure out for my simple requirement that is I wanted to send the only header (eg: sales order header) without sending for items info as my GW is having only one entity that doesn't have any association. can please help me as very new in OData? thx. - Swami
Hi Swami,
Sorry for very late reply, till now, you may have already addressed the requirement.
However, For your case, you require only one structure to get Header input.
Here, no association or navigation, rest steps should remain same, it will support POST operation.
Thanks & Regards,
Dilip
Hi Dilip,
How to process if I have multiple headers as inputs ?
Hi Sweta,
Sorry for late reply.
If you have multiple headers, then you create one entity for Header, like you have created for Item, and attach both to one common Mai_Header entity. Main_Header's Field can be set blank.
Similar plan I have suggested in below reply in query against Sai.
Thanks & Regards,
Dilip
Great blog. I have a similar requirement.
Hi Sai Sreenivas,
You can do like below,
Thanks & Regards,
Dilip
Hello Dilip,
Thanks a lot for the excellent blog.
I have a requirement where an array of values has to be passed to a property of an SAP OData EntitySet.
An example of the call that would be made is :
"Updates": [ { "Email": "", "LongText": "", "MutipleArray": [ { "out": "12345678", "in": "a1234567" } ] } ]
I want to process the property 'MultipleArray' for which an array of values would be passed. Could you please let me know how it can be handled in ABAP.
Thanks,
Sushanth
Hi Sushanth,
Sorry for late response, till now, I haven't came across such a nested requirement, so I can't comment in a concrete manner.
But, suppose, as per this blog's case, if I need to pass Header, ITEM and TAX_ITEM, then would be managing three entity-set having association/navigation tech. Here, each ITEM line may have multiple TAX_ITEM line.
You can take reference from std. app's nested odataService example.
Thanks & Regards,
Dilip P.
Hii Can You please provide the purchase order using OData service using BAPI programming through RFC connection using frontend as JavaScript in eclipse .
Hi, Jasonrev,
In your case, following techniques can be followed:
Thanks & Regards,
Dilip
can you please provide the full material for oDataService,manage EntitySets and BAPI coding
Hi Jason,
Check below blog link, you will get enough hint
https://blogs.sap.com/2017/11/19/sap-fiori-odata-service-creation/
https://blogs.sap.com/2018/04/10/sap-fiori-odata-service-examples/
Thanks & Regards,
Dilip
I need JavaScript coding in eclipse
Hi Jasonrev,
Check last part this blog to get JavaScript coding to consume oDataService
https://blogs.sap.com/2018/03/30/call-odata-service-in-eclipse-fiori-app/
Thanks & regards,
Dilip
Hi Dilip,
I have one Odata service with POST method and json input/request. The external app ( Mule) calls the SAP odata service with GET to fetch the token and when making POST call it supplies the same token fetched via the GET call. Surprising SAP gives a 403 Forbidden error .
I debugged SAP internal code and looks like it gives this error is due to mismatch of the token code.
SAP internally calls the security context class/method and gets the token for that call and tries to match it with the token which came during the API call.
Security context is not the correct token and does not match with GET call token.
From Postman it works fine as expected i.e GET and POST but when calling API from Mulesoft it gives 403 error.
Any idea on this issue ?
I can have this working by disabling the x-csrf-token but that not the ideal approach .
Thanks
Govind Parmar
Govind Parmar
Hi Govind,
Please suggest external-App-developer Team to call odAtaServices on data 'Submit' button event in below sequence:
Tokens has expiry limit, so ideally, when token access and posting data should happen in same session call in sequence.
Thanks & Regards,
Dilip Pandey
Thank you so much Dilip. I followed both your blogs for Multiple Table output and Multiple table input and it worked perfect. Such a great explanation and nothing can go wrong anywhere. I made couple of mistakes but after reading your steps again and again I was able to fix it. Thank you so much for your efforts in helping developers like me.
Thanks for the detailed steps Dilip. I have one question, Is it possible to have Result entity only in the response payload? Without having it in request payload as blank?
I am referring to below highlighted point
Shabnam
Hi Shabnam J,
Sorry for late reply. I haven't tried yet.
There should be one option like RFC's Export/Import parameters, in similar way, when returning the output from OData, option to skip request structures (Entity 'Header', 'Item').
If I get it, will post here.
Thanks & Regards,
Dilip Pandey
Dilip:
I want to send 100 json "rows" to Odata in one POST call and get back a "row" for each in a table.
See example data below below...Can this be done? I have been trying for one week and I have lost hope that it is possible. I'm getting desperate...
Can you advise me?
Joe K.
Json:
{ "Id":"00", "Id":"01", "Id":"02", "Id":"03",..... "Id":"99", }
Hello Sir,
Thanks for the nice blog. One quick question. I've follow the steps to create and activate all the objects.
However there is some error during testing. Below is the error message.
Would you mind to have a look and advice what I need to do to fix that? Thank you and have a great day ahead.
<?xml version="1.0" encoding="UTF-8"?>
-<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>005056A509B11EE3AEB5819C07C69E2F</code>
<message xml:lang="en">The server is refusing to process the request because the entity has an unsupported format</message>
-<innererror xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<transactionid>66A168EF1AB300F0E006161661B85F8A</transactionid>
<timestamp>20211105125822.4624270</timestamp>
-<Error_Resolution>
<SAP_Transaction>For backend administrators: use ADT feed reader "SAP Gateway Error Log" or run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details</SAP_Transaction>
<SAP_Note>See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)</SAP_Note>
</Error_Resolution>
</innererror>
</error>