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)):
// get all learning paths
var query = spAppUtils.getAppODataApiUrl()
+ "/web/lists/getbytitle('Learning Paths')/Items"
+ "?$select=Id,Title,Published,Keywords1,OData__Comments"
+ "&$filter=Published eq '" + ((published) ? 1 : 0) + "'"
+ "&$orderby=Title";
// execute query
return $.ajax(oDataUtils.getRequest(query))
.then(onSuccess)
.fail(onGetLearningPathFail);
As are creates…
//create new object
var payload = buildJsonLearningItemPayload(learningItem);
endpoint = spAppUtils.getAppODataApiUrl()
+ "/web/lists/getbytitle('Learning Items')/Items";
requestData = oDataUtils.newItemRequest(endpoint, payload);
// add handlers
requestData.success = function (response) { deferred.resolve(response); };
requestData.error = function (error) { deferred.reject(error); };
// submit query
$.ajax(requestData);
and updates…
//update existing object
var payload = buildJsonLearningItemPayload(learningItem)
endpoint = learningItem._permalink();
requestData = oDataUtils.updateItemRequest(endpoint, payload, learningItem._etag());
// add handlers
requestData.success = function (response) { deferred.resolve(response); };
requestData.error = function (error) { deferred.reject(error); };
// submit query
$.ajax(requestData);
Or deletes…
//delete existing object
var endpoint = learningItem._permalink();
var requestData = oDataUtils.deleteItemRequest(endpoint);
// add handlers
requestData.success = function (response) { deferred.resolve(response); };
requestData.error = function (error) { deferred.reject(error); };
// submit query
$.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:
/* Create a JSON object to post to the learning item */
function buildJsonLearningItemPayload(learningItem) {
var payload = {
__metadata: { "type": "SP.Data.LearningItemsListItem" },
Title: learningItem.Title(),
OData__Comments: learningItem.Description(),
URL: {Url: learningItem.URL(),
Description: learningItem.URL()},
ItemType: learningItem.ItemType(),
LearningPathId: learningItem.AssociatedLearningPath().Id()
};
return JSON.stringify(payload);
};
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.