Categories
Skip Navigation Links

$batch calls - CRUD operations using SharePoint REST API

Performance is a key aspect of any application. In this article, we will show how to perform BULK or BATCH calls on SharePoint objects using REST APIs. Using a batch call, you can combine several REST calls to a single call. This will greatly help in improving the performance load on your application. Let’s go in detail.


This article is performed on SharePoint Online. We are going to perform Create, Read, Update and Delete operation using the batch call of SharePoint REST API.

Key points about $batch call

  • Batch calls are available in SharePoint Online, SharePoint 2016 and onwards.
  • While performing the operation, if you get any error in one changeset/operation, the rest of the changeset will take place. Right now, there’s no “All OR Nothing” functionality available for this.
  • You can batch changesets from different lists/libraries but of the same site. You CANNOT bulk update in two different lists of different sites.
  • Only A Part of the batch can be READ operation. There cannot be multiple read operations in a single batch. But in the single batch call, there can be multiple Insert, Update or Delete operation
  • Each operation of the batch should have its own REST endpoint

Structure of the Batch calling

Before you go through the examples, just refer to the figure below.

  • Batch: Your entire call to the server is called a Batch.
  • Changeset: Each individual function (Create/Update/Delete) is called one changeset. You can accommodate as many as 100 changesets in a single batch call.
  • Structure of the sharepoint rest api Batch call
  • For batch processing, you will need two GUIDs. One for batch and one for each Changeset.
  • When Batch starts, you need to specify batch GUID in the format --batch_batchGUID.
  • For each changeset, you need to specify changeset GUID. --changeset_changesetGUID. For each changeset, the GUID will remain the same for a single call.
  • At the end of the last changeset, you need to close it like this, --changeset_changesetGUID--
  • At the end of the batch call you need to close it like this --batch_batchGUID--

Create List Items using $batch

List: List Name

Columns: Title, Description

Requirement: Create three rows in a single batch call using the SharePoint REST API. You can create more rows and perform this operation in more than one list within the same site.

  • function CreateListItemsBatchCall() {
  •     // Create a JSON object which will have all the records/rows that we need to create in the SharePoint list
  •     var ListData = undefined;
  •     ListData = [
  •         {
  •             __metadata: {
  •                 // Format of the "type" is: SP.Data.<>ListItem
  •                 type: 'SP.Data.List_x0020_NameListItem'
  •             },
  •             Title: 'Title 1',
  •             Description: 'Description 1'
  •         },
  •         {
  •             __metadata: {
  •                 type: 'SP.Data.List_x0020_NameListItem'
  •             },
  •             Title: 'Title 2',
  •             Description: 'Description 2'
  •         },
  •         {
  •             __metadata: {
  •                 type: 'SP.Data.List_x0020_NameListItem'
  •             },
  •             Title: 'Title 3',
  •             Description: 'Description 3'
  •         }
  •     ];
  •  
  •     StartBatchRequest(ListData);
  • }
  •  
  • // This function is used to generate GUIDs for Batch and Changeset
  • function GenerateGUID() {
  •     return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
  •         var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
  •         return v.toString(16);
  •     });
  • }
  •  
  • function StartBatchRequest(ListData) {
  •     // Every batch will have a Batch ID/GUID
  •     var batchGuid = GenerateGUID();
  •  
  •     // Create the body of the request
  •     var batchContents = new Array();
  •  
  •     // Every changeset/action will have have a ChangeSet ID/GUID
  •     var changeSetGUID = GenerateGUID();
  •  
  •     // Iterate through each record
  •     for (var i = 0; i < ListData.length; i++) {
  •         // create the request endpoint
  •         var endpoint = _spPageContextInfo.webAbsoluteUrl
  •             + '/_api/web/lists/getbytitle(\'List Name\')'
  •             + '/items';
  •  
  •         // create the changeset
  •         batchContents.push('--changeset_' + changeSetGUID);
  •         batchContents.push('Content-Type: application/http');
  •         batchContents.push('Content-Transfer-Encoding: binary');
  •         batchContents.push('');
  •         batchContents.push('POST ' + endpoint + ' HTTP/1.1');
  •         batchContents.push('Content-Type: application/json;odata=verbose');
  •         batchContents.push('');
  •         batchContents.push(JSON.stringify(ListData[i]));
  •         batchContents.push('');
  •     }
  •     // END changeset to create data
  •     batchContents.push('--changeset_' + changeSetGUID + '--');
  •  
  •     // batch body
  •     var batchBody = batchContents.join('\r\n');
  •  
  •     batchContents = new Array();
  •  
  •     // create a batch for creating items
  •     batchContents.push('--batch_' + batchGuid);
  •     batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetGUID + '"');
  •     batchContents.push('Content-Length: ' + batchBody.length);
  •     batchContents.push('Content-Transfer-Encoding: binary');
  •     batchContents.push('');
  •     batchContents.push(batchBody);
  •     batchContents.push('');
  •  
  •     batchContents.push('--batch_' + batchGuid + '--');
  •     batchBody = batchContents.join('\r\n');
  •  
  •     // Request endpoint for the entire batch
  •     var endpoint = _spPageContextInfo.webAbsoluteUrl + '/_api/$batch';
  •  
  •     var batchRequestHeader = {
  •         'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
  •         'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
  •     };
  •  
  •     // create request
  •     jQuery.ajax({
  •         url: endpoint,
  •         type: 'POST',
  •         headers: batchRequestHeader,
  •         data: batchBody,
  •         success: function (response) {
  •             console.log(response);
  •         },
  •         fail: function (error) {
  •             console.log(response);
  •         }
  •     });
  • }

In the Fiddler, you can check the HTTP traffic generated for this action.

Fiddler traffic for sharepoint rest api batch call

Update List Items using $batch

List: List Name, Customer

Requirement: Update two rows of two different lists in a single batch call using SharePoint REST API. You can use this code to perform an update in bulk.

  • function UpdateListItemsBatchCall() {
  •     // Here we will update two different list items from two different lists in a single REST call
  •     // each batch should have a Batch ID
  •     var batchGuid = GenerateGUID();
  •     // each update should have a ChangeSet ID
  •     var changeSetGUID = GenerateGUID();
  •     // creating the body
  •     var batchContents = new Array();
  •     // Request creation for first list item update
  •     var endpoint1 = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('List Name')/items(20)";
  •     var ListData1 = null;
  •     ListData1 = [
  •         {
  •             __metadata: {
  •                 // Format of the "type" is: SP.Data.<>ListItem
  •                 type: 'SP.Data.List_x0020_NameListItem'
  •             },
  •             Description: "Updated Description"
  •         }
  •     ];
  •     // create the changeset
  •     batchContents.push('--changeset_' + changeSetGUID);
  •     batchContents.push('Content-Type: application/http');
  •     batchContents.push('Content-Transfer-Encoding: binary');
  •     batchContents.push('');
  •     batchContents.push('MERGE ' + endpoint1 + ' HTTP/1.1');
  •     batchContents.push('Content-Type: application/json;odata=verbose');
  •     batchContents.push('Accept: application/json;odata=verbose');
  •     batchContents.push('IF-MATCH: *');
  •     batchContents.push('');
  •     batchContents.push(JSON.stringify(ListData1[0]));
  •     batchContents.push('');
  •     // Request creation for second list item update
  •     var endpoint2 = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Customer')/items(1)";
  •     var ListData2 = null;
  •     ListData2 = [
  •         {
  •             __metadata: {
  •                 // Format of the "type" is: SP.Data.<>ListItem
  •                 type: 'SP.Data.CustomerListItem'
  •             },
  •             Amount: 50
  •         }
  •     ];
  •     // create the changeset
  •     batchContents.push('--changeset_' + changeSetGUID);
  •     batchContents.push('Content-Type: application/http');
  •     batchContents.push('Content-Transfer-Encoding: binary');
  •     batchContents.push('');
  •     batchContents.push('MERGE ' + endpoint2 + ' HTTP/1.1');
  •     batchContents.push('Content-Type: application/json;odata=verbose');
  •     batchContents.push('Accept: application/json;odata=verbose');
  •     batchContents.push('IF-MATCH: *');
  •     batchContents.push('');
  •     batchContents.push(JSON.stringify(ListData2[0]));
  •     batchContents.push('');
  •     batchContents.push('--changeset_' + changeSetGUID + '--');
  •     // batch body
  •     var batchBody = batchContents.join('\r\n');
  •     batchContents = new Array();
  •     // create a batch for creating items
  •     batchContents.push('--batch_' + batchGuid);
  •     batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetGUID + '"');
  •     batchContents.push('Content-Length: ' + batchBody.length);
  •     batchContents.push('Content-Transfer-Encoding: binary');
  •     batchContents.push('');
  •     batchContents.push(batchBody);
  •     batchContents.push('');
  •     batchContents.push('--batch_' + batchGuid + '--');
  •     batchBody = batchContents.join('\r\n');
  •     // create the request endpoint
  •     var endpoint = _spPageContextInfo.webAbsoluteUrl + '/_api/$batch';
  •     var batchRequestHeader = {
  •         'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
  •         'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
  •     };
  •     // create request
  •     jQuery.ajax({
  •         url: endpoint,
  •         type: 'POST',
  •         headers: batchRequestHeader,
  •         data: batchBody,
  •         success: function (response) {
  •             console.log(response);
  •         },
  •         fail: function (error) {
  •             console.log(response);
  •         }
  •     });
  • }
  • // This function is used to generate guids for Batch and Changeset
  • function GenerateGUID() {
  •     return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
  •         var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
  •         return v.toString(16);
  •     });
  • }

Delete List Items using $batch

List: List Name, Customer

Requirement: Delete two rows of two different lists in a single batch call using SharePoint REST API. You can use this code to perform Delete in bulk according to your requirements.

  • function DeleteListItemsBatchCall() {
  •     // Here we will delete two different list items from two different lists in a single REST call
  •     // Every batch will have a Batch ID/GUID
  •     var batchGuid = GenerateGUID();
  •  
  •     // Every delete/changeset should have a ChangeSet ID/GUID
  •     var changeSetGUID = GenerateGUID();
  •  
  •     // creating the body
  •     var batchContents = new Array();
  •  
  •     // Request creation for first list item Delete
  •     var endpoint1 = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('List Name')/items(20)";
  •  
  •     // create the changeset
  •     batchContents.push('--changeset_' + changeSetGUID);
  •     batchContents.push('Content-Type: application/http');
  •     batchContents.push('Content-Transfer-Encoding: binary');
  •     batchContents.push('');
  •     batchContents.push('DELETE ' + endpoint1 + ' HTTP/1.1');
  •     batchContents.push('Content-Type: application/json;odata=verbose');
  •     batchContents.push('Accept: application/json;odata=verbose');
  •     batchContents.push('IF-MATCH: *');
  •     batchContents.push('');
  •  
  •     // Request creation for second list item Delete
  •     var endpoint2 = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Customer')/items(1)";
  •  
  •     // create the changeset
  •     batchContents.push('--changeset_' + changeSetGUID);
  •     batchContents.push('Content-Type: application/http');
  •     batchContents.push('Content-Transfer-Encoding: binary');
  •     batchContents.push('');
  •     batchContents.push('DELETE ' + endpoint2 + ' HTTP/1.1');
  •     batchContents.push('Content-Type: application/json;odata=verbose');
  •     batchContents.push('Accept: application/json;odata=verbose');
  •     batchContents.push('IF-MATCH: *');
  •     batchContents.push('');
  •  
  •     batchContents.push('--changeset_' + changeSetGUID + '--');
  •  
  •     // batch body
  •     var batchBody = batchContents.join('\r\n');
  •  
  •     batchContents = new Array();
  •  
  •     // create a batch for creating items
  •     batchContents.push('--batch_' + batchGuid);
  •     batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetGUID + '"');
  •     batchContents.push('Content-Length: ' + batchBody.length);
  •     batchContents.push('Content-Transfer-Encoding: binary');
  •     batchContents.push('');
  •     batchContents.push(batchBody);
  •     batchContents.push('');
  •  
  •     batchContents.push('--batch_' + batchGuid + '--');
  •     batchBody = batchContents.join('\r\n');
  •  
  •     // create the request endpoint
  •     var endpoint = _spPageContextInfo.webAbsoluteUrl + '/_api/$batch';
  •  
  •     var batchRequestHeader = {
  •         'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
  •         'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
  •     };
  •  
  •     // create request
  •     jQuery.ajax({
  •         url: endpoint,
  •         type: 'POST',
  •         headers: batchRequestHeader,
  •         data: batchBody,
  •         success: function (response) {
  •             console.log(response);
  •         },
  •         fail: function (error) {
  •             console.log(response);
  •         }
  •     });
  •  
  • }
  •  
  • // This function is used to generate GUIDs for Batch and Changeset
  • function GenerateGUID() {
  •     return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
  •         var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
  •         return v.toString(16);
  •     });
  • }

Conclusion:

We went through the understanding of batch calls and how we can perform CRUD operations in bulk using SharePoint REST API examples.


We value your Feedback:

Page URL:

Name:

 

Email:

 
 

Suggestion:

 

© 2020 Code SharePoint