I’ve written before on some of the reasons why I prefer to work with the SharePoint 2013 REST API over the client-side-object-model (CSOM) for custom solutions. The only time I prefer to use the CSOM is when there’s something that isn’t exposed in the SharePoint REST API. But when working with list data, I get everything I need with the REST API.
SharePoint 2013 REST API with jQuery
One of the downsides though is that you generally have to write a lot more plumbing.
SharePoint 2013 REST API - SELECT ALL
Here’s what a request looks like for a bunch of items in a list using jQuery and the REST API:
// get multiple items
var requestUri = _spPageContextInfo.webAbsoluteUrl +
'/_api/Web/Lists/getByTitle(\'Contacts\')/items/' +
'?$select=Id,FirstName,Title,Email'
// execute AJAX request
var requestHeaders = {
'accept': 'application/json;odata=verbose'
};
$.ajax({
url: requestUri,
contentType: 'application/json;odata=verbose',
headers: requestHeaders,
success: function (response){ /* do something on success */ },
error: function(error){ /* do something on fail */ }
});
SharePoint 2013 REST API - SELECT ONE
Here’s what a request looks like for a simple select of one item in a list using jQuery and the REST API:
// get one item
var requestUri = _spPageContextInfo.webAbsoluteUrl +
'/_api/Web/Lists/getByTitle(\'Contacts\')/items/' +
'?$select=Id,FirstName,Title,Email' +
'&$filter=Id eq 1'
// execute AJAX request
var requestHeaders = {
'accept': 'application/json;odata=verbose'
};
$.ajax({
url: requestUri,
contentType: 'application/json;odata=verbose',
headers: requestHeaders,
success: function (response){ /* do something on success */ },
error: function(error){ /* do something on fail */ }
});
SharePoint 2013 REST API - UPDATE ITEM
And here’s what an update looks like (inserts and deletes are very similar):
// update an item
var requestUri = _spPageContextInfo.webAbsoluteUrl +
'/_api/Web/Lists/getByTitle(\'Contacts\')/items(1)';
var requestHeaders = {
'Accept': 'application/json;odata=verbose',
'X-RequestDigest': $('#__REQUESTDIGEST').val(),
'X-HTTP-Method': 'MERGE',
'If-Match': etag
};
var customerData = {
__metadata: { 'type': 'SP.Data.ContactsListItem' },
Title: 'NewName',
};
requestBody = JSON.stringify(customerData);
$.ajax({
url: requestUri,
type: 'POST',
contentType: 'application/json;odata=verbose',
headers: requestHeaders,
data: JSON.stringify(customerData);,
success: function (response){ /* do something on success */ },
error: function(error){ /* do something on fail */ }
});
That’s a bunch of code right? How about something easier?
Introducing BreezeJS
Allow me to introduce you to a slick client-side library: Breeze! In a nutshell, Breeze is Entity Framework in the client… or to the non-Microsoft developer, it’s a client-side ORM.
OK, so how will this benefit developers? The Breeze website does a pretty good job of making the case. In no particular order here’s why I love using it:
- LINQ Style Queries: As you’ll see from the code snippets below in this post, when you want to work with data, you can write your queries using the familiar LINQ style syntax, enabling you to chain calls, sort using
orderby()
and filter usingwhere()
to name a few. - Client-Side Cache: When Breeze gets data from the server, it stores it in a local cache. You get to use this local cache to spare trips to the server or to batch up a handful of changes to multiple items.
- Automatic Validation: Breeze also allows you to define some validation logic in your entities. Some things are built in, like checking for valid dates & times, URLs, emails, phone numbers, max string lengths, non-nullable fields… you name it. If you try to save your changes, Breeze throws validation errors before sending the request to the server.
- Abstracting Away the Data Access Plumbing: I can’t stress this one enough. Just like LINQ in server-side code abstracts away the queries we have to write, Breeze does the same for us on the client-size. This means we can have much cleaner code and less of a change in forgetting that single quote mart, a closing parentheses, the question mark for the query string… you get the picture.
There’s a little set up work that you need to do that I got into in another post, Getting BreezeJS to Work with the SharePoint 2013 REST API, but for now just look at how much cooler this is…
Selecting Items From a List with Breeze
To start, let’s compare the SELECT ALL above… here’s how I’d write the exact same thing with Breeze:
breeze.EntityQuery
.from(contactType.defaultResourceName)
.using(entityManager)
.execute()
.then(function (response) {
var results = response.results;
// write results > div
if (results && results.length) {
var message = '';
for (var index = 0; index < results.length; index++) {
message += results[index].FirstName
+ ' ' + results[index].Title
+ ' (' + results[index].Email + ')';
}
jQuery("#results").html(message);
}
});
Pretty simple huh? That’s just the start…how about selecting just one or a subset of items?
breeze.EntityQuery
.from(contactType.defaultResourceName)
.using(entityManager)
.execute()
.then(function (response) {
var results = response.results;
// write results > div
if (results && results.length) {
var message = '';
for (var index = 0; index < results.length; index++) {
message += results[index].FirstName
+ ' ' + results[index].Title
+ ' (' + results[index].Email + ')';
}
jQuery("#results").html(message);
}
});
Just a simple where()
statement added… nothing more!
Updating Items with Breeze
Selects are always easy, but what about updating items with Breeze? In the code above I showed you how to do it with just the raw SharePoint 2013 REST API using jQuery. It involves recreating the entire request back and updating the specific items. Thankfully you don’t have to do that with Breeze!
As I said above Breeze is very much like Entity Framework in the client. One thing it does is cache a local copy of the entity. As you make updates to the entity, it preserves the changes separate from the original. So to update an item you first get it, then you simply save your changes! Assuming you got a single item using the code I used above you can make your change first, then simply call save as I’m doing below:
// get the first item
var promise = breeze.EntityQuery
.from(contactType.defaultResourceName)
.using(entityManager)
.execute()
.where('Id', 'eq', 1)
.then(function (data) {
return data.entity;
});
// update the first item
promise.then(function (contact) {
contact.Title = 'NewName';
entityManager.saveChanges().then(function () {
jQuery("#results").html('saved first item in list');
});
});
Preserving Round Trips to the Server with the Local Cache in Breeze
So, let’s say you’ve created a page that shows a list of items. You want your users to have the ability select one and view the details on that one item. How would we go about that? Check this little nugget of code out. It says to try to get the item from the local cache first, but if it isn’t there, then try to get it from the server:
// try to get a single item from the cache, then revert to server
entityManager.fetchEntityByKey('Contact', 1, true)
.then(function (data) {
var message = data.entity.FirstName
+ ' ' + data.entity.Title
+ ' (' + data.entity.Email + ')';
message += 'pulled from: ' + (data.fromCache ? 'cache' : 'server');
jQuery("#results").html(message);
});
Pretty cool huh? There’s so much more we can do with Breeze… but first you have a little work you need to do to get it working with SharePoint. Out of the box it doesn’t… and in my next post I’ll explain why it doesn’t work out of the box and what you need to do to set it up.