Skip to Content

Build OData Batch Requests for Writing Data with SAP Cloud SDK's Virtual Data Model

test
0 %
Build OData Batch Requests for Writing Data with SAP Cloud SDK's Virtual Data Model
Details
// Explore More Tutorials

Build OData Batch Requests for Writing Data with SAP Cloud SDK's Virtual Data Model

11/07/2019

Build OData batch requests for writing data with the SAP Cloud SDK's Virtual Data Model in your Address Manager application.

You will learn

  • How to use the Virtual Data Model to create multiple entities in one request
  • How to trigger a batch request consisting of multiple change sets from an API endpoint exposed by your application

The goal of this tutorial group is to continue implementing the TypeScript/JavaScript web application you built in the Build an Address Manager with the SAP Cloud SDK’s OData Virtual Data Model tutorials by using the OData Batch request feature of the SAP Cloud SDK.

In this tutorial, you use the batch changeset for creating multiple business partner addresses via an API endpoint.


Step 1: What is OData batch?

In the previous tutorials, you learned how to leverage the SAP Cloud SDK to build queries for basic OData operations. The basic OData operations allow you to

  • query entities (e.g., BusinessPartnerAddress) with the same type
  • create an entity
  • update an entity
  • delete an entity

as one operation in one HTTP request.

However, imagine that you may want to update 100 entities (e.g., business partner address). With the basic OData operations, you have to send 100 HTTP requests, which is slow and not atomic. Essentially, the OData protocol also supports batch processing, which is so-called OData batch request. With the power of the batch processing, you can avoid network overhead ( 1 request V.S. N requests ) and benefit from its atomic behavior.

Changeset consists of a collection of write operations (create, update or delete) and behaves like a database transaction. This means, that either all operations are executed successfully, or none of them. You will build the batch changesets in this tutorial. Retrieve requests, i.e., the read operation, is also supported and will be introduced in the next tutorial.

Log on to answer question
Step 2: Prepare your application

As one of the prerequisites, you should have read the tutorials and you should have a running application with a connection to an SAP S/4HANA Cloud system by using the SAP Cloud SDK’s Virtual Data Model.

Now open the package.json and update the dependency versions like below, since the OData batch request feature is released in the version 1.11.2.

"dependencies": {
  "@sap/cloud-sdk-core": "^1.11.2",
  "@sap/cloud-sdk-vdm-business-partner-service": "^1.11.2",
  ...
}

Run npm install in your root folder to install/update the dependencies.

Log on to answer question
Step 3: Add an API endpoint

Create a file with the name batch-changeset-route.ts in the root folder and then copy the code below to the file:

import { Request, Response } from 'express';
import {
  batch,
  BusinessPartnerAddress,
  changeset
} from "@sap/cloud-sdk-vdm-business-partner-service";
import { BatchResponse, WriteResponses } from "@sap/cloud-sdk-core";

export function batchChangesetRoute(req: Request, res: Response) {
  const addresses = req.body.addresses as any[];
  batch(
      changeset(
        ...addresses.map(address =>
          BusinessPartnerAddress.requestBuilder().create(
            BusinessPartnerAddress.builder().fromJson(address)
          )
        )
      )
    )
    .execute({
      url: 'https://my.s4hana.ondemand.com/'
    })
    .then(batchResult => {
      const success = 'success';
      res.status(200).send(success);
    })
    .catch(error => {
      res.status(500).send(error.message);
    });
}

Replace the url with your system info.

Open the application.ts, add the router definition and the missing import.

...
import { batchChangeSetRoute } from "./batch-changeset-route";
...
private routes(): void {
  const router = express.Router();
...
  // please add this line starts
  router.post("/batch-changeset/create", batchChangesetRoute);
  // please add this line ends
  this.app.use("/", router);
}

Create a file with the name batch-changeset-route.js in the root folder and then copy the code below to the file:

const { batch, BusinessPartnerAddress, changeset } = require('@sap/cloud-sdk-vdm-business-partner-service');

export function batchChangesetRoute(req, res) {
  const addresses = req.body.addresses;
  batch(
      changeset(
        ...addresses.map(address =>
          BusinessPartnerAddress.requestBuilder().create(BusinessPartnerAddress.builder().fromJson(address))
        )
      )
    )
    .execute({
      url: 'https://my.s4hana.ondemand.com/'
    })
    .then(batchResult => {
      const success = 'success';
      res.status(200).send(success);
    })
    .catch(error => {
      res.status(500).send(error.message);
    });
}

Replace the url with your system info.

Open the application.js, add the router definition and the missing import.

...
const { batchChangeSetRoute } require ('./batch-changeset-route');
...
private routes() {
  const router = express.Router();
...
  // please add this line starts
  router.post("/batch-changeset/create", batchChangesetRoute);
  // please add this line ends
  this.app.use("/", router);
}

Please note, post is used as the method of the batch-changeset endpoint, aligned with the OData Batch. Now you can start the application locally by executing the command npm run start:local or npm run serve-debug as debug mode.

Log on to answer question
Step 4: Test by creating addresses in batch request

After starting your application you can make a request with post as the method, localhost:8080/batch-changeset as the url and the json body:

{
	"addresses" :[
		{
			"businessPartner": "1000000","country": "DE","postalCode": "14469","cityName": "potsdam","streetName": "Konrad-Zuse-Ring","houseNumber": "10"
		},
		{
			"businessPartner": "1000000","country": "DE","postalCode": "14469","cityName": "potsdam","streetName": "Konrad-Zuse-Ring","houseNumber": "11"
		}
	]
}

Make sure you use the proper business partner id in your cloud system.

You should see the success as the response body, meaning that two business partner addresses are created.

Log on to answer question
Step 5: Build entities from response

Now I’ll show you how to build type-safe BusinessPartnerAddress entities by using the SDK.

Copy the function below to your batch-changeset-route.ts file.

function convertBatchResponse(batchResponse: BatchResponse): BusinessPartnerAddress[]{
  return (batchResponse as WriteResponses).responses.map(r=> r.as!(r.type!) as BusinessPartnerAddress);
}

First of all, based on the changeset in the batch requests you sent, you know the batch responses are WriteResponses instead of ReadResponse. Secondly, by calling as(Constructable<Entity>), the responses are cast to Entity. Then, the Entity is eventually cast to BusinessPartnerAddress by using as keyword. This is essential, because during compile time, the type of the entity is not clear. Only you as the caller can provide the entity type based on the order of the changesets.

Now you can comment out the old code and replace it by using the one below in the batch-changeset-route.ts file:

...
        .then(batchResult =>{
          // const success = 'success';
          // res.status(200).send(success);
          const entities = batchResult.map(convertBatchResponse);
          res.status(200).send(entities);
        })
...

Now I’ll show you how to build BusinessPartnerAddress entities by using the SDK.

Copy the function below to your batch-changeset-route.js file.

function convertBatchResponse(batchResponse) {
  return batchResponse.responses;
}

Now you can comment out the old code and replace it by using the one below in the batch-changeset-route.js file:

...
        .then(batchResult =>{
          // const success = 'success';
          // res.status(200).send(success);
          const entities = batchResult.map(convertBatchResponse);
          res.status(200).send(entities);
        })
...

Restart your server and call the request example again in the Step 4.

You create 2 business partner addresses as shown in the response example:

[
    [
        {
            "businessPartner": "1000000",
            "addressId": "40160",
            "addressUuid": "fa163e1c-91b4-1ed9-bec5-2b469753c6e6",
            ...
            "cityName": "potsdam",
            "country": "DE",
            "houseNumber": "10",
            "postalCode": "14469",
            "streetName": "Konrad-Zuse-Ring",
            ...
        },
        {
            "businessPartner": "1000000",
            "addressId": "40160",
            "addressUuid": "fa163e1c-91b4-1ed9-bec5-2b469753c6e6",
            ...
            "cityName": "potsdam",
            "country": "DE",
            "houseNumber": "11",
            "postalCode": "14469",
            "streetName": "Konrad-Zuse-Ring",
            ...
        }
    ]
]
Log on to answer question
Step 6: Wrap up

In this tutorial, you learned how to make an OData batch request with the SAP Cloud SDK’s Virtual Data Model for writing data to your cloud system, and you built your own application that can send multiple changesets in one batch request.

Log on to answer question
Step 7: Test yourself
In which scenarios, do you need the OData batch?
×

Next Steps

Prerequisites

Back to top