In my last post, BreezeJS Makes Client-Side SharePoint 2013 REST Development a... BREEZE!, I introduced you to the Breeze library and demonstrated how it can make your life as a SharePoint client-side developer easier. However not all things are point-&-click in SharePoint land, right? In this post I'll walk you through the “why” part Breeze doesn't work out of the box (OOTB) with SharePoint's REST API and the “how” you can get around it to make it work for you.
Understanding How Breeze Works
In order for Breeze to give you all the awesome things I touched on in the previous post, it needs to have a client-side understanding of the data structures on the server. This is exactly how LINQ or Entity Framework works... it needs context... or a data context. OOTB Breeze has a server-side component that you can snap onto Entity Framework data contexts and other server side options. But this isn't required... which is good because in today's world of SharePoint development we should try to stay away from using the server-side API if possible.
There is also a client-side component you can use on it's own. One cool thing about this piece is you can point to an existing OData service and Breeze can request it's metadata (using the
$metadata operator) and generate the entities on the fly for you.
SharePoint and Breeze Didn't Hit it Off
Breeze understands OData metadata responses so you're thinking “fantastic... the April 2013 Cumulative Update for SharePoint 2013 and thus SharePoint Online added the
$metadata operator!” Unfortunately it's not that simple. There are a few issues with SharePoint's OData implementation as it stands today that cause issues for Breeze:
SharePoint's OData Metadata Response is HUGE
Have you ever inspected SharePoint's OData metadata default response? I'm talking about just a simple site using the Developer Site or Team Site template? It's over 600kb! That means every page that uses Breeze would need to request this... that's a damn expensive request for each page!
SharePoint's OData API Doesn't Support Batching
This has been something I've wanted for a long time. Unfortunately batching, which is part of the OData specification, hasn't been implemented by the SharePoint team as of this post. This would allow us to batch a lot of requests (like multiple updates, deletes or inserts) into one HTTP request like we can with the client-side-object-model (CSOM). Unfortunately Breeze uses batches to issue any HTTP POST... which is the right thing to do to cut down on the number of requests.
Some SharePoint's HTTP Request Requirement aren't OData Standards
Some of these fall back to the fact that SharePoint's OData API was implemented as some HTTP and OData specifications were being updated, so they were left to create some of their own implementations. For instance, the requirement that all HTTP POST and DELETE requests include the
X-RequestDigest in the header. Also if you are updating items and don't want to overwrite the whole object, but just the fields you supply it, SharePoint doesn't use the HTTP MERGE verb, rather you issue an HTTP POST with a
X-HTTP-METHOD header set to MERGE.
Breeze has no idea about these things or how to deal with them unfortunately.
Breeze Doesn't Understand Some Things in the Metadata Response
There are a few artifacts within the SharePoint OData metadata response that Breeze simply doesn't understand. Now I'm not passing judgement on who's fault this is because it doesn't really matter... the other two issues are significant enough to be non-starters.
For more information on working with Breeze and SharePoint, check out my upcoming new Pluralsight course, coming soon in March 2014 now available: Building SharePoint Apps as Single Page Apps with AngularJS. Module 5 is all about using Breeze with SharePoint.*
Never Give Up Hope - Breeze is Extensible!
What's cool here is that there is no dead end at this point... even though I've painted a pretty grim picture. See, the guys who wrote Breeze at IdeaBlade were smart enough and have the forethought to make it an extensible library!
A few weeks back I sat down with Ward Bell, one of the brains behind Breeze and did a good bit of paired programming over Skype to resolve this. My job was to educate him on how SharePoint worked, his job was to take that knowledge and map it to Breeze. What we came up with was a slick addition to the Breeze Labs: a SharePoint Data Service Adapter.
Introducing the Breeze SharePoint Data Service Adapter
Basically this library, which you can get via a NuGet package Breeze.DataService.SharePoint overrides how Breeze natively handles OData services and adds logic to handle SharePoint's OData service!
This brings Breeze support to those developers using the SharePoint 2013 OData [REST] API you have in SharePoint 2013 On-Premises and SharePoint Online in Office 365!
You will have to write a tiny bit of configuration code, telling Breeze to use this data service adapter and how to obtain the value for the
X-RequestDigest header to use on HTTP POST and DELETE requests.
Another thing you'll have to do is create the metadata to give Breeze for the lists you want to talk to in SharePoint. Why? Well, Breeze has some issues with the metadata response in the SharePoint OData service. But not only that, you don't want to let Breeze build that dynamically because (1) you are looking at a minimum 600kb download for every single page that uses the Breeze library and (2) you are always going to get the whole feed, so you'll be building a massive metadata model in the client within Breeze, bloating the memory requirements of the page and the page load time.
In my next post, Getting BreezeJS to Work with the SharePoint 2013 REST API, I walk you through the steps you need to employ to get Breeze working with the SharePoint 2013 REST API.