Skip to Content
Technical Articles

Batch operation in in OData V4 Adapter in SAP Cloud Integration

In this post you will be able to learn how to integrate an OData V4 system through SAP Cloud Integration using $batch method. The OData V4 adapter now provides support for $batch operation. This method is very useful when you need to perform multiple requests. As the name suggests this operation helps you to club multiple HTTP requests into one request. This will result in improved performance for the same.

At present, the OData adapter supports the following OData operations

  1. GET (Query)
  2. POST (Create)
  3. PUT(Update)
  4. DELETE (Delete)
  5. FUNCTION IMPORT

Configuring Batch in OData V4 Adapter

We will be using the OData Demo V4 service, http://services.odata.org/(S(btmy2xygehkm1gfrnpezr4xx))/V4/OData/OData.svc in this example.

To model a batch operation you will have to select the “Batch Processing ($batch)” option as the Operation in the processing tab of the adapter

To model the batch scenario click on the “Select” button to open the querybuilder dialog. Once the dialog opens provide the connection information as shown below.

After you click on “Step 2” button you will be presented with the “Select Entity and DefineOperation” screen as shown below.

Click on “Add ChangeSet” to to add a changeset which will include a “batchChangeSetPart” section. ChangeSets are used for place data modification request such as “POST/PUT/DELETE”. For Data Retrieval requests you can click on “Add Batchset” to add batchset. For You can add more ChangeSetParts to a ChangeSet using “+” icons. Each ChangeSetPart or BatchSet will contain an entity. You can change the entity for which you want to model the requests. Below the table you will be able to specify the name for the XSD schema file which will be generated for this model. The XSD file which will be generated once the Finish button is clicked.

This XSD schema will define the input payload for the batch operation. You can use the XSD schema to validate the payload by putting a mapping step before the OData V4 adapter.

Let us examine the different type of payloads required for different operations.

Request Payload formats

The supported input type to the OData V4 adapter is xml at present. The xml payload is converted to json in case of non-batch operations and multipart/mixed format in case of batch operations by the adapter.

For the batch operation the input xml should be enclosed within a “batchParts” tag. It can contain any number of “batchSets” and “batchChangeSet” tags according to the requirements. The “batchChangeSet” tag can contain any number of “batchChangeSetPart” tags inside “batchChangeSet” tag.

Each “batchSet” and “batchChangeSetPart” tag should contain the following tags for one http request

  1. method : This is a mandatory tag. Should contain values of the HTTP operation such as GET, PUT, POST, DELETE, FUNCTION_IMPORT
  2. uri : This is a mandatory tag which should specify the relative url of the HTTP call to the service url.
  3. headers : This is an optional field, It can contain any custom headers required for the specific HTTP call.
  4. body : This is an optional field, This is required for PUT and POST operations, where the payload for an entity has to be specified.

 

Response Payload Formats

The output of the Odata V4 adapter is also in XML format. The output xml will be enclosed within a “batchPartsResponse” tag. Each “batchSet” will have a corresponding “batchSetResponse” and each “batchChangeSet” and “batchChangeSetPart” will have a “batchChangeSetResponse” and “batchChangeSetPartResponse” sections. Each response section will have the following sections

  1. statusInfo: The HTTP status of the request.
  2. statusCode: The HTTP response code of the request.
  3. body: The response body of the request will be contained in this section.
  4. headers : The response headers of the HTTP request.

 

Here are some example request and response payloads for different operations.

POST

Sample Request

<batchParts>
	<batchChangeSet1>
		<batchChangeSetPart1>
			<method>POST</method>
			<uri>Products</uri>
			<body>
				<Products>
					<Product>
						<ID>101</ID>
						<Name>Macbook pro</Name>
						<ReleaseDate>2019-01-01T00:00:00Z</ReleaseDate>
						<Rating>5</Rating>
						<Price>1500</Price>
					</Product>
				</Products>
			</body>
		</batchChangeSetPart1>
		<batchChangeSetPart2>
			<method>POST</method>
			<uri>Categories</uri>
			<body>
				<Categories>
					<Category>
						<ID>101</ID>
						<Name>Laptops</Name>
					</Category>
				</Categories>
			</body>
		</batchChangeSetPart2>
	</batchChangeSet1>
</batchParts>

Sample Response

<?xml version='1.0' encoding='UTF-8'?>
<batchPartsResponse>
	<batchChangeSetResponse>
		<batchChangeSetPartResponse>
			<headers>
				<header>
					<headerName>Cache-Control</headerName>
					<headerValue>no-cache</headerValue>
				</header>
				<header>
					<headerName>Content-Type</headerName>
					<headerValue>application/json;odata.metadata=full;odata.streaming=true;IEEE754Compatible=false;charset=utf-8</headerValue>
				</header>
				<header>
					<headerName>Location</headerName>
					<headerValue>https://services.odata.org/V4/OData/(S(CPI_batch_abc))/OData.svc/Products(101)</headerValue>
				</header>
				<header>
					<headerName>OData-Version</headerName>
					<headerValue>4.0;</headerValue>
				</header>
				<header>
					<headerName>X-Content-Type-Options</headerName>
					<headerValue>nosniff</headerValue>
				</header>
			</headers>
			<statusInfo>Created</statusInfo>
			<body>
				<Products>
					<Product>
						<Description/>
						<Price>1500.0</Price>
						<Rating>5</Rating>
						<DiscontinuedDate/>
						<ID>101</ID>
						<ReleaseDate>2019-01-01T00:00:00Z</ReleaseDate>
						<Name>Macbook pro</Name>
					</Product>
				</Products>
			</body>
			<statusCode>201</statusCode>
		</batchChangeSetPartResponse>
		<batchChangeSetPartResponse>
			<headers>
				<header>
					<headerName>Cache-Control</headerName>
					<headerValue>no-cache</headerValue>
				</header>
				<header>
					<headerName>Content-Type</headerName>
					<headerValue>application/json;odata.metadata=full;odata.streaming=true;IEEE754Compatible=false;charset=utf-8</headerValue>
				</header>
				<header>
					<headerName>Location</headerName>
					<headerValue>https://services.odata.org/V4/OData/(S(CPI_batch_abc))/OData.svc/Categories(101)</headerValue>
				</header>
				<header>
					<headerName>OData-Version</headerName>
					<headerValue>4.0;</headerValue>
				</header>
				<header>
					<headerName>X-Content-Type-Options</headerName>
					<headerValue>nosniff</headerValue>
				</header>
			</headers>
			<statusInfo>Created</statusInfo>
			<body>
				<Categories>
					<Category>
						<ID>101</ID>
						<Name>Laptops</Name>
					</Category>
				</Categories>
			</body>
			<statusCode>201</statusCode>
		</batchChangeSetPartResponse>
	</batchChangeSetResponse>
</batchPartsResponse>

GET operation

Sample Request

<batchParts>
	<batchSet1>
		<method>GET</method>
		<uri>Products(101)</uri>
		<headers>
			<header>
				<headerName>Accept</headerName>
				<headerValue>application/json;odata.metadata=minimal</headerValue>
			</header>
		</headers>
	</batchSet1>
	<batchSet2>
		<method>GET</method>
		<uri>Categories(101)</uri>
		<headers>
			<header>
				<headerName>Accept</headerName>
				<headerValue>application/json;odata.metadata=minimal</headerValue>
			</header>
		</headers>
	</batchSet2>
</batchParts>

Sample Response

<?xml version='1.0' encoding='UTF-8'?>
<batchPartsResponse>
	<batchSetResponse>
		<headers>
			<header>
				<headerName>Cache-Control</headerName>
				<headerValue>no-cache</headerValue>
			</header>
			<header>
				<headerName>Content-Type</headerName>
				<headerValue>application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8</headerValue>
			</header>
			<header>
				<headerName>OData-Version</headerName>
				<headerValue>4.0;</headerValue>
			</header>
			<header>
				<headerName>X-Content-Type-Options</headerName>
				<headerValue>nosniff</headerValue>
			</header>
		</headers>
		<statusInfo>OK</statusInfo>
		<body>
			<Products>
				<Product>
					<Description/>
					<Price>1500.0</Price>
					<Rating>5</Rating>
					<DiscontinuedDate/>
					<ID>101</ID>
					<ReleaseDate>2019-01-01T00:00:00Z</ReleaseDate>
					<Name>Macbook pro</Name>
				</Product>
			</Products>
		</body>
		<statusCode>200</statusCode>
	</batchSetResponse>
	<batchSetResponse>
		<headers>
			<header>
				<headerName>Cache-Control</headerName>
				<headerValue>no-cache</headerValue>
			</header>
			<header>
				<headerName>Content-Type</headerName>
				<headerValue>application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8</headerValue>
			</header>
			<header>
				<headerName>OData-Version</headerName>
				<headerValue>4.0;</headerValue>
			</header>
			<header>
				<headerName>X-Content-Type-Options</headerName>
				<headerValue>nosniff</headerValue>
			</header>
		</headers>
		<statusInfo>OK</statusInfo>
		<body>
			<Categories>
				<Category>
					<ID>101</ID>
					<Name>Laptops</Name>
				</Category>
			</Categories>
		</body>
		<statusCode>200</statusCode>
	</batchSetResponse>
</batchPartsResponse>

UPDATE

Sample request

<batchParts>
	<batchChangeSet1>
		<batchChangeSetPart1>
			<method>PUT</method>
			<uri>Products(101)</uri>
			<body>
				<Products>
					<Product>
						<ID>101</ID>
						<Name>Macbook pro</Name>
						<ReleaseDate>2019-01-01T00:00:00Z</ReleaseDate>
						<Rating>4</Rating>
						<Price>2000</Price>
					</Product>
				</Products>
			</body>
		</batchChangeSetPart1>
		<batchChangeSetPart2>
			<method>PUT</method>
			<uri>Categories(101)</uri>
			<body>
				<Categories>
					<Category>
						<ID>101</ID>
						<Name>Laptops and Chromebooks</Name>
					</Category>
				</Categories>
			</body>
		</batchChangeSetPart2>
	</batchChangeSet1>
</batchParts>

Sample Response

<?xml version='1.0' encoding='UTF-8'?>
<batchPartsResponse>
	<batchChangeSetResponse>
		<batchChangeSetPartResponse>
			<headers>
				<header>
					<headerName>Cache-Control</headerName>
					<headerValue>no-cache</headerValue>
				</header>
				<header>
					<headerName>OData-Version</headerName>
					<headerValue>4.0;</headerValue>
				</header>
				<header>
					<headerName>X-Content-Type-Options</headerName>
					<headerValue>nosniff</headerValue>
				</header>
			</headers>
			<statusInfo>No Content</statusInfo>
			<statusCode>204</statusCode>
		</batchChangeSetPartResponse>
		<batchChangeSetPartResponse>
			<headers>
				<header>
					<headerName>Cache-Control</headerName>
					<headerValue>no-cache</headerValue>
				</header>
				<header>
					<headerName>OData-Version</headerName>
					<headerValue>4.0;</headerValue>
				</header>
				<header>
					<headerName>X-Content-Type-Options</headerName>
					<headerValue>nosniff</headerValue>
				</header>
			</headers>
			<statusInfo>No Content</statusInfo>
			<statusCode>204</statusCode>
		</batchChangeSetPartResponse>
	</batchChangeSetResponse>
</batchPartsResponse>

DELETE

Sample Request

<batchParts>
	<batchChangeSet1>
		<batchChangeSetPart1>
			<method>DELETE</method>
			<uri>Products(101)</uri>
		</batchChangeSetPart1>
		<batchChangeSetPart2>
			<method>DELETE</method>
			<uri>Categories(101)</uri>
		</batchChangeSetPart2>
	</batchChangeSet1>
</batchParts>

Sample Response

<?xml version='1.0' encoding='UTF-8'?>
<batchPartsResponse>
	<batchChangeSetResponse>
		<batchChangeSetPartResponse>
			<headers>
				<header>
					<headerName>Cache-Control</headerName>
					<headerValue>no-cache</headerValue>
				</header>
				<header>
					<headerName>OData-Version</headerName>
					<headerValue>4.0;</headerValue>
				</header>
				<header>
					<headerName>X-Content-Type-Options</headerName>
					<headerValue>nosniff</headerValue>
				</header>
			</headers>
			<statusInfo>No Content</statusInfo>
			<statusCode>204</statusCode>
		</batchChangeSetPartResponse>
		<batchChangeSetPartResponse>
			<headers>
				<header>
					<headerName>Cache-Control</headerName>
					<headerValue>no-cache</headerValue>
				</header>
				<header>
					<headerName>OData-Version</headerName>
					<headerValue>4.0;</headerValue>
				</header>
				<header>
					<headerName>X-Content-Type-Options</headerName>
					<headerValue>nosniff</headerValue>
				</header>
			</headers>
			<statusInfo>No Content</statusInfo>
			<statusCode>204</statusCode>
		</batchChangeSetPartResponse>
	</batchChangeSetResponse>
</batchPartsResponse>

Function Import

Sample Request

<?xml version="1.0" encoding="UTF-8"?>
<batchParts>
	<batchSet1>
		<method>FUNCTION_IMPORT</method>
		<uri>GetNearestAirport(lon=-118,lat=33)</uri>
		<headers>
			<header>
				<headerName>Accept</headerName>
				<headerValue>application/json;odata.metadata=minimal</headerValue>
			</header>
		</headers>
	</batchSet1>
</batchParts>

Sample Response

<?xml version='1.0' encoding='UTF-8'?>
<batchPartsResponse>
	<batchSetResponse>
		<headers>
			<header>
				<headerName>Content-Type</headerName>
				<headerValue>application/json; odata.metadata=minimal</headerValue>
			</header>
			<header>
				<headerName>OData-Version</headerName>
				<headerValue>4.0</headerValue>
			</header>
		</headers>
		<statusInfo>OK</statusInfo>
		<body>
			<Airports>
				<Airport>
					<IataCode>LAX</IataCode>
					<IcaoCode>KLAX</IcaoCode>
					<Name>Los Angeles International Airport</Name>
					<Location>
						<Address>1 World Way, Los Angeles, CA, 90045</Address>
						<Loc>GEOGRAPHY'SRID=4326;Point(-118.408055555556 33.9425)'</Loc>
						<City>
							<Name>Los Angeles</Name>
							<CountryRegion>United States</CountryRegion>
							<Region>California</Region>
						</City>
					</Location>
				</Airport>
			</Airports>
		</body>
		<statusCode>200</statusCode>
	</batchSetResponse>
</batchPartsResponse>
Be the first to leave a comment
You must be Logged on to comment or reply to a post.