Why the SharePoint REST API is Better than SharePoint's CSOM

3 min read

As a SharePoint developer, I explain why I prefer REST API over CSOM despite its downsides. Learn about its advantages & access a wide range of samples.


A few months ago I wrote how I prefer using the REST API in SHAREPOINT over using the CSOM. Sure there are some downsides to this (no coverage for workflow or taxonomy, no batching just to name a few). However the advantages outweigh the downsides (3rd part libraries and frameworks mostly work with REST, more standards, more samples because it isn’t SharePoint specific, etc).

One complaint I get from people is from the fact you have a bit more code to write for each call. Sure… you have to build the request each time, but that’s just an opportunity for reuse.

I’ve created two libraries I use for all my SharePoint REST calls that really cut down on constantly rewriting the same thing over and over. At the same time, this makes it a lot more readable.

The first one is used to get the SharePoint specific URLs:

The second one is for generating the calls for reads & writes. As you can see, different methods are used for different tasks:

And now, when I want to get data, the call is quite clean (the following examples are from my SharePoint 2013 App, a SharePoint Hosted App implemented as a Single Page Application (SPA)):

 1// get all learning paths
 2var query = spAppUtils.getAppODataApiUrl()
 3+ "/web/lists/getbytitle('Learning Paths')/Items"
 4+ "?$select=Id,Title,Published,Keywords1,OData__Comments"
 5+ "&$filter=Published eq '" + ((published) ? 1 : 0) + "'"
 6+ "&$orderby=Title";
 7
 8// execute query
 9return $.ajax(oDataUtils.getRequest(query))
10.then(onSuccess)
11.fail(onGetLearningPathFail);

As are creates…

 1//create new object
 2var payload = buildJsonLearningItemPayload(learningItem);
 3endpoint = spAppUtils.getAppODataApiUrl()
 4+ "/web/lists/getbytitle('Learning Items')/Items";
 5requestData = oDataUtils.newItemRequest(endpoint, payload);
 6
 7// add handlers
 8requestData.success = function (response) { deferred.resolve(response); };
 9requestData.error = function (error) { deferred.reject(error); };
10
11// submit query
12$.ajax(requestData);

and updates…

 1//update existing object
 2var payload = buildJsonLearningItemPayload(learningItem)
 3endpoint = learningItem._permalink();
 4requestData = oDataUtils.updateItemRequest(endpoint, payload, learningItem._etag());
 5
 6// add handlers
 7requestData.success = function (response) { deferred.resolve(response); };
 8requestData.error = function (error) { deferred.reject(error); };
 9
10// submit query
11$.ajax(requestData);

Or deletes…

 1//delete existing object
 2var endpoint = learningItem._permalink();
 3var requestData = oDataUtils.deleteItemRequest(endpoint);
 4
 5// add handlers
 6requestData.success = function (response) { deferred.resolve(response); };
 7requestData.error = function (error) { deferred.reject(error); };
 8
 9// submit query
10$.ajax(requestData);

In the samples above, I use the same method for creating the object I’m going to send to the rest services in the create-update-delete operations:

 1/* Create a JSON object to post to the learning item */
 2function buildJsonLearningItemPayload(learningItem) {
 3  var payload = {
 4    __metadata: { "type": "SP.Data.LearningItemsListItem" },
 5    Title: learningItem.Title(),
 6    OData__Comments: learningItem.Description(),
 7    URL: {Url: learningItem.URL(),
 8    Description: learningItem.URL()},
 9    ItemType: learningItem.ItemType(),
10    LearningPathId: learningItem.AssociatedLearningPath().Id()
11    };
12
13  return JSON.stringify(payload);
14};

Cool huh? In reality I combine these two in my SharePoint projects. I broke them up here for readability. If I’m not working in SharePoint, I don’t need the stuff in the first script.

Share this article

Feedback & comments