As you work with APIs from SAP S/4HANA Cloud (S/4HC), you may encounter some APIs that have a built in feature for change control that require additional handling when calling the API known as an ETag. The sales order API is a common API that requires the use of ETags when modifying an order.
In this blog, we'll take a quick look at an example of how to handle ETags when they are required to call SAP S/4HC APIs. Entity Tags, or ETags is basically version control for updating documents over OData. It's to make sure you are working and updating the latest version of a document. This is done as a parameter in the HTTP Header that provides version information on the document requested/updated. This is required for OData services because a resource is not locked for updating ahead of the update (i.e. before being called) and is called an opportunistic locking. There are many resources available on the internet with good info on ETags, but here is a good overview blog. ETags are not required for document creation.
As an example of how ETags function, let's imagine that you have a billing document with a line item that has 5 items to be picked. While you are making your call to pick 4 items, another system has come along and picked all 5 items thereby leaving none left to pick. Your call would now fail when you go to pick 5 items because there arent 5 left to be picked as you are working with data from an older version of the document. To prevent this situation you fetch the document version ahead of the update and present this version as part of your update for S/4HC to validate that you have the latest version. For example, document with 5 items to be picked is v002. The non SAP S/4HC system fetches the document version first and puts v002 into the ETag header. Now the other resource comes along and picks 4 the document version increases to v003. Now my OData call with fail because I am not working with the correct version of the document (v002 vs v003). This logic is used in many of the SAP APIs to provide data consistency and integrity.
In this example, we will use the Outbound Delivery API from SAP S/4HC: https://api.sap.com/api/API_OUTBOUND_DELIVERY_SRV/resource
This API is unique because not only does it have OData services, it also has a series of HTTPS services that accept only an HTTP POST using query string parameters around the topic of picking.
For this blog, we'll test using Postman but you can implement this same logic in an iFlow on SAP Cloud Platform Integration (CPI).
The first step is to call the API to fetch the x-csrf-token AND the ETag values. We'll work with delivery document 800000037 and line item 20. You will find the values returned in the Header response, highlighted in yellow in the below image.
To update the batch, we need to set the header values in our request and then form the JSON payload for updating the delivery document. This is shown in the next two screen shots.
The batch is updated in SAP:
In the next step, a call the picking service to update picked quantity is made. This is one of the services available in the API hub described above. What's unique about these services is that they only take a URL with query string parameters (no body) and the only response is an HTTP 200 for a success or an error message.
If this service was being called on its own, we would need to fetch the x-csrf-token and the ETag value but since we just updated the document for batch number we can simply increment our ETag value by 1 and reuse the same x-csrf-token.
The reply indicates a successful call:
Picking quantity is updated in SAP S/4HC:
You could keep calling different services, for example, you might want to call the Post Goods Issue (PGI) service to do a PGI on the document. You just need to increment ETag by 1 and call the PGI service, /PostGoodsIssue (assuming nothing else has come along and called your document in the meantime or an end user saved the document in SAP S/4HC).
In addition, you can test all of these services in the API hub too--you don't have to use Postman.
I hope you found this blog useful.