Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
arunchembra1
Participant

This blog contains information regarding batch concept in SAP NetWeaver Gateway Consumers . The OData Batch requests allow the grouping of multiple operations into a single HTTP request payload. I have seen lot of discussion regarding the  batch concept.

This is a brief blog to explain how to implement batch in SAP system and how to make batch gateway service calls for READ,CREATE and UPDATE.

In SAP we don't have to write any additional logic to implement batch, just have to redefine/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN and/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END methods as shown below.

READ :

Example of executing a batch request containing multiple Read operations.

URL:

http://**************/sap/opu/odata/sap/<Main_Service_Name>/$batch

HEADER:

Authorization: SAP ID & PASSWORD

x-csrf-token:   Enter Token

Content-Type: multipart/mixed; boundary=batch

BODY:

--batch

Content-Type: application/http

Content-Transfer-Encoding: binary

Accept: application/xml

GET ABCCollection/?$filter= EMP_ID eq '10000030' HTTP/1.1

--batch

Content-Type: application/http

Content-Transfer-Encoding: binary

Accept: application/jsonxml

GET ABCCollection/?$filter=EMP_ID eq '10000031' HTTP/1.1

  --batch--

CREATE:

Example of executing a batch request containing multiple Create operations.

URL:


http://**************/sap/opu/odata/sap/<Main_Service_Name>/$batch

HEADER :

Authorization: SAP ID & PASSWORD

x-csrf-token:   Enter Token

Content-Type: multipart/mixed; boundary=batch

    

BODY:

--batch

Content-Type: multipart/mixed; boundary=changeset

--changeset

Content-Type: application/http

Content-Transfer-Encoding: binary

POST ABCCollection HTTP/1.1

Content-Type: application/atom+xml

Content-Length: 588

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<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:EMP_ID>10000033</d:EMP_ID>

<d:FIRST_NAME>MIKE</d:FIRST_NAME>

<d:LAST_NAME>JOHNSON</d:LAST_NAME>

</m:properties>

</atom:content>

</atom:entry>

--changeset

Content-Type: application/http

Content-Transfer-Encoding: binary

POST ABCCollection HTTP/1.1

Content-Type: application/atom+xml

Content-Length: 588

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<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:EMP_ID>10000034</d:EMP_ID>

<d:FIRST_NAME>ALLAN</d:FIRST_NAME>

<d:LAST_NAME>XAVIER</d:LAST_NAME>

</m:properties>

</atom:content>

</atom:entry>

--changeset--

--batch--

UPDATE:

Example of executing a batch request containing multiple Update operations(Change names).

URL:


http://**************/sap/opu/odata/sap/<Main_Service_Name>/$batch

HEADER :

Authorization: SAP ID & PASSWORD

x-csrf-token:   Enter Token

Content-Type: multipart/mixed; boundary=batch

    

BODY:

--batch

Content-Type: multipart/mixed; boundary=changeset

--changeset

Content-Type: application/http

Content-Transfer-Encoding: binary

PUT ABCCollection('10000033') HTTP/1.1

Content-Type: application/atom+xml

Content-Length: 588

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<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:EMP_ID>10000033</d:EMP_ID>

<d:FIRST_NAME>MIKE_CHANGE</d:FIRST_NAME>

<d:LAST_NAME>JOHNSON_CHANGE</d:LAST_NAME>

</m:properties>

</atom:content>

</atom:entry>

--changeset

Content-Type: application/http

Content-Transfer-Encoding: binary

PUT ABCCollection('10000034') HTTP/1.1

Content-Type: application/atom+xml

Content-Length: 588

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<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:EMP_ID>10000034</d:EMP_ID>

<d:FIRST_NAME>ALLAN_CHANGE</d:FIRST_NAME>

<d:LAST_NAME>XAVIER_CHANGE</d:LAST_NAME>

</m:properties>

</atom:content>

</atom:entry>

--changeset--

--batch--

Reference Links:

http://help.sap.com/saphelp_gateway20sp06/helpdata/en/90/dc8363306c47d3b2fca1398f5de94b/content.htm

http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/40546820-3ea7-2f10-dfab-be373c0da...

30 Comments
Former Member
0 Kudos

Nice Blog, thank you. It will be very helpful.

Former Member
0 Kudos

Thanks Chembra

Nice Blog..

arunchembra1
Participant
0 Kudos

Thanks Pinaki........ :smile:

arunchembra1
Participant
0 Kudos

Thanks Suman........ :smile:

Former Member
0 Kudos

For batch read I have put the following content on the BODY part

--batch

Content-Type: application/http

Content-Transfer-Encoding: binary


GET ABCCollection(ID='123',DESC='ABC') HTTP/1.1


--batch--

You are passing filter parameters, I guess its batch query.

Regards,

Pinaki

arunchembra1
Participant
0 Kudos

Thanks pinaki instead of Read i put Query in my document...

former_member209120
Active Contributor
0 Kudos

Hi Arun Chembra,

Nice document, Thanks for sharing...

Regards,

Ramesh.T

arunchembra1
Participant
0 Kudos

Thanks Ramesh

Former Member
0 Kudos

Good one Arun.

Former Member
0 Kudos

Hi Arun,

     Your Blog Helped me alot.

      I can Succesfully send the Data To backend from REST Client.

      Presently I am Doing Update Operation For Sales Order i.e change of quantity ,rejection ...

     my problem is we cannot send the data from Mobile Device the data to backend.

     please suggest me a way how to pass the Request Body from Mobile Side.

Regards,

Raju.

woutdejong
Participant
0 Kudos

Arun, nice blog.

Do you happen to have any advanced examples, like an implementation (use case) of the /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN method in combination with its sibling /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END?

I see some hints in the docs what one can do with these, but not any actual example.

Cheers, Wout

arunchembra1
Participant

Hi Wout,

Thanks for your feedback...

Even i was not sure about the real time scenarios where we can implement the /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN method in combination with its sibling /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END .

While using batch you will not be able to use BAPI_TRANSACTION_COMMIT in this case you can implement the /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN and /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END to resolve this issue.

Thanks,

Arun

woutdejong
Participant
0 Kudos

Hi Arun, yeah, indeed I haven't found any, except a ref in the help about preparing internal tables in BEGIN, then I assume filling internal tables in the individual CUD operations, and then committing the internal tables to the db in the END method.

I'm not sure however, how to pass along those internal tables. I can only come up with via MEMORY, but usually I regard that as a bad choice. Plus the individual CUD operations then need to be aware whether they are called within a CHANGESET or not.

Cheers, Wout

arunchembra1
Participant
0 Kudos

Hi Wout,

Yes, we have to achieve this via memory only, even though it was a bad choice :cool: .

Thanks,

Arun

woutdejong
Participant
0 Kudos

Sorry Arun, I'm overcomplicating things with the MEMORY stuff. As all CHANGESET logic and CUD operations happen inside 1 instance of the Data Provider Class, you can just define attributes ("internal tables") to store the data and get that data in the CHANGESET_END method.

Former Member
0 Kudos

Hi Wout,

How did you accomplish to do this with the member table in the data provider class?  Even when in the same changeset I noticed the runtime is reinstantiated for each change. So in my case I set the member variable "is_batch_request" in /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN.  When I check for the variable in my entity's ENTITYSET_UPDATE_ENTITY, the variable is only initialized for the first entry of the batch request (within the same change set).. 
When looking at the above code (see screenshot), it seems not possible to work with a member table? (Create + clear runtime)  Or am I missing something?

Thanks in advance!

Former Member
0 Kudos

Hi Bjorn,

probably you already found out, I think you can use static member variables in the data provider class. These seem to be shared among the changes of a change set. This worked in a small test I did.

Best regards,

Matthias

Former Member
0 Kudos

Hi Matthias,

Using a static member variable did the trick, thanks a lot!

Kr,

Bjorn

Former Member
0 Kudos

For what i can understand, if I prepare a service with the Batch option and send multiple create operations, it will treat each one as individual and not by a whole right?

I have a table that needs to be analysed completely in a Create Operation but I'm not sure if the batch methods will work.

Former Member
0 Kudos

Hi Joel,

By using the batch request all changes you add to that batch changeset will be processed via one http request, saving you the separate round trips to the server.

For each create operation you added to the batch request however, the entityset_create_entity method will be called, acting on that single entry. I think my problem was similar to yours, and used a flag to have different behaviors in the create_entity method for normal and batch requests. In case of batch request, you can set a flag in the CHANGESET_BEGIN method of the DPC. When the batch flag is active, I do not update the entity in the database in the create_entity method, but instead append it to a member table of the DPC. After the last entry of the batch request, the CHANGESET_END method will be called, where you will have access to the entire table and can decide whether or not to write it to the database. Note that for this to work, both the flag and the table need to be static member attributes of the data provider class.
Hope this clears things up for you!

Kind regars,

Bjorn

woutdejong
Participant
0 Kudos

Bjorn, sorry for the very late reply. I did use instance attributes, and this still works, as I'm just revisiting the code. (This is an embedded Gateway deployment.)

Not sure why the runtime is not reinstated in my case...

Cheers, Wout

woutdejong
Participant
0 Kudos

In addition to Bjorn's answer. 1 Batch can contain multiple Changesets. A Changeset behaves transactionally. Please checkout the documentation on help.sap.com; it's pretty clear.

Pavan_Golesar
Active Participant
0 Kudos

nice Blog..... Was very informatic and helpful.. 😃

Regards,

Pavan Golesar

Former Member
0 Kudos

Sorry but it doesn't feel like adding EXIT in the changeset_end and changeset_begin will  solve sending multiple entries for one entityset problem.

Former Member
0 Kudos

I have to admit, that your statement is right. I can't get my batch UPDATE to work.

Former Member
0 Kudos

Hello! Interesting blog, but how would creating these batch requests look like from the front-end using javascript/json?

former_member218528
Participant
0 Kudos

Hi Arun ..! Thanks for the post.It helped me a lot.I have small doubt regarding header part.

what value should we pass to this x-csrf-token in header section..



Former Member
0 Kudos

Hi Arun,

I am getting status code 202  during my POST create operation , but not getting any other info in response area …even I put a external break point at create_entity …but still execution  was not stopped there ..

Appreciate your help ..I paste below request

-batch
Content-Type: multipart/mixed; boundary=changeset

–changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

POST SorditemSet HTTP/1.1
Content-Type: application/atom+xml
Content-Length: 588

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>
<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:Erdat>20161115</d:Erdat>
<d:Netwr>    94.35</d:Netwr>
<d:Waerk>GBP</d:Waerk>
<d:Kunnr>0000001066</d:Kunnr>
<d:Posnr>000010</d:Posnr>
<d:Matnr>90251178</d:Matnr>
<d:Kwmeng>    1.000</d:Kwmeng>
<d:Status>UNAU</d:Status>
<d:Vbeln>40000336</d:Vbeln>
</m:properties>
</atom:content>
</atom:entry>

–changeset–
–batch–-

Appreciate your help …if I am missing anything ..

Kind Regards
Sthiru

former_member197071
Participant
0 Kudos
Where exactly we have to write business logic? Example reading and saving payload data into tables.
0 Kudos
Hi, hello, I am having a problem now, when I call the request to create a purchase order, an error occurs as follows: <?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>457B9545FD6B0210E005BD3B9E76C48A</transactionid>
<timestamp>20181106012253.0217930</timestamp>
<Error_Resolution>
<SAP_Transaction>For backend administrators: 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>
My request address is: https://my300052-api.saps4hanacloud.cn/sap/opu/odata/sap/API_PURCHASEORDER_PROCESS_SRV/$batch
The parameters are: {
"PurchaseOrder": "4500000122",
"CompanyCode": "A010",
"PurchaseOrderType": "NB",
"Supplier": "1000000040",
"PurchasingOrganization": "A010",
"PurchasingGroup": "001",
"to_PurchaseOrderItem": {
"results": [
{
"PurchaseOrder": "4500000122",
"PurchaseOrderItem": "10",
"Plant": "A010",
"OrderQuantity": "10",
"PurchaseOrderQuantityUnit": "KG",
"PurchaseOrderItemCategory": "0",
"Material": "T62-15160000-0",
"to_AccountAssignment": {
"results": [
{
"PurchaseOrder": "4500000122",
"PurchaseOrderItem": "10",
"AccountAssignmentNumber": "1"
}
]
},
"to_PurchaseOrderPricingElement": {
"results": [
{
"PurchaseOrder": "4500000122",
"PurchaseOrderItem": "10",
"PricingDocument": "1000000229",
"PricingDocumentItem": "10",
"PricingProcedureStep": "60",
"PricingProcedureCounter": "1",
"FactorForConditionBasisValue": 3.14
}
]
},
"to_ScheduleLine": {
"results": [
{
"PurchasingDocument": "7000000000",
"PurchasingDocumentItem": "10",
"ScheduleLine": "1"
}
]
}
}
]
}
}
Labels in this area