Why the SharePoint REST API is Better than SharePoint's CSOM
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.