secret
Last active

initial thoughts and reactions to Breeze.js

  • Download Gist
thoughtsOnBreeze.md
Markdown

Having never used Breeze.js prior to yesterday, I spent some time with my co-worker Brandon Satrom, to figure out what it is all about, how to make it work with a simple back-end API, and how to integrate Breeze in to our Kendo UI DataSource object. The idea is to allow someone that is already taking advantage of Breeze, to use our control suite and bind controls such as the Grid, ListView, TreeView and others to data provided by Breeze.

Overall: I Like What I See

I was honestly skeptical about what Breeze would provide when I first looked through the site. I didn't quite see the value of having yet another library to manage API calls. But having worked through a basic sample, used the API, and looked at the integration points and documentation that you provide for Angular and Knockout, I am seeing more value in it than I thought I would. The fluent API and LINQ-like structure of the API was familiar and easy to use once I got passed the initial hurdles, which I'll outline below. The consistency in the API, no matter the front-end framework and UI control suite being used, is a good thing - especially in larger applications or in systems where there is a mix of old and new, legacy and modern.

As I noted on twitter, though, I did run in to a few surprised and issues. Ultimately I worked through these, but it was a bit frustrating at first.

Default Setup: WebAPI?

I downloaded the core runtime files and opened up the samples on the website to get things running. I was rather surprised and somewhat pained to see that all of the examples assumed ASP.NET MVC4 as the server, with WebAPI as the API layer. I understand the needs for a default setup in order to get people up and running quickly. This wasn't the set that I was expecting, though. It honestly took me a while to get over that shock. But I dug in and looked around for info on how to use something else ...

... and I found almost no information on how to change the defaults in the samples and tutorials. There were consistent references that said things like "but you don't have to use ASP.NET" without ever pointing to any documentation to show how to not use it.

I don't have any particular problem with .NET development. I spent 10 years doing it and consider it one of my core competencies. My major hurdle at this point, though, is being on a Mac and not having a virtual machine to spin up quickly in order to hack away at a test site. For reference, I consider the ability to get a sample project off the ground quickly to be very important and I wanted to hack away at a PHP site with a hard coded JSON file as the API, just to get it working fast. Thus, the shock of seeing WebAPI as the defaults and dismay at not being able to find documentation on how to change the defaults, lead to some frustration.

Suggestion: Show A Complete HTML Setup

I work for Kendo UI, now, but was a fan of Telerik's products for a long time, prior. One of my favorite aspects of the documentation for Kendo and most of Telerik, is the ability to look at a demo and click a button to view the HTML and JavaScript source, right there in my browser.

While the tutorials for Breeze did provide good information and options on what API methods to call, when, they did not provide the complete structure the way Kendo UI and Telerik products do. At least, not through the website. I understand the download with the sample projects would have this, but I was having problems with the .zip files on my Mac, and could only get the runtime zip file to unpack.

This made it somewhat difficult for me to figure out what files needed to be included in my project, and in what order. I'm sure if I had been able to open the sample zip file it would have been easier. But to get the right order, I had to find an online demo and view source on the page. This wasn't too difficult, but it took me a few minutes of looking around the site to find what I needed and then view source.

Having a more complete example, with the full HTML layout and a complete JavaScript file that implements a simple API call would go a long way to alleviate this. A set up like this should be the very first item in the tutorial so that people who have never used Breeze can get it running with copy & paste instead of hunting down the right order of which files to include.

Saving Grace For Non-.NET Servers: The API Documentation

After some digging, trial and error, and reading through the API documentation, I found reference to the objects that I needed to create in order to specify both an end-point for the API I wanted to call, and to say that my service did not provide any metadata. It was the API documentation that made it possible for me to get passed the initial hurdle of the defaults.

Even at that, though, I had to make a lot of assumptions and guesses through trial and error. This was relatively easy to do since I'm familiar with .NET and it's conventions. The names that you provided in your objects and options were evident to me, and I appreciated the API documentation being as thorough as it is.

I think a little more effort on the docs could go a long way to getting past the .NET defaults. It was mentioned, via twitter, that this is in the works. If you need any reviewers and suggestions for this once you get a basic outline done, please let me konw. I'd love to help out with those docs if I can, to make it easier for developers with other back-ends.

OData Parameters?

The other shocker for the API calls was that all of the parameters I set up with my query ended up as OData parameters to my service call. Again, this makes sense in the context of WebAPI. I haven't heard of many (if any) people and companies outside of the Microsoft platform realms using OData, though. I don't know that this is a tremendously huge problem... but my experience with OData parameters and services has been less than pleasant. I fought with it pretty hard when building the front-end for RavenHQ, and advocated for not using it in another project due to the pain I had.

Is it possible to not use OData as the query parameters? Is that something that can easily be changed with a configuration option, like the hasMetaData setting? If not, this is something that I would suggest looking at. I don't know if support for OData queries and syntax will be widly accepted outside of .NET developers.

Integrating With Kendo UI Was Very Simple!

It took around an hour to go from

I have not idea what I'm doing

to

Like A Boss

with the core of Breeze, and then another hour or so to wrap our heads around getting it integrated in to a Kendo UI datasource. All things said and done, I found the API and experience of working with Breeze to be ... a breeze (see what I did there? :P).

To get the most basic of Kendo UI integrations done, we decided to wrap a custom transport for our DataSource around the Breeze API. For more information on this, see my post on how I did this with a Backbone.Collection.

The assumption we made is that we should not dictate any of the DataService or EntityManager configuration for the Breeze client set up. We let the developer determine all of that. What we did take control of, though, was the EntityQuery object in our custom transport. This let us use the options and parameters provided through our Kendo UI DataSource to format the query object appropriately, and call our API through Breeze to get data in to our DataSource.

Here's what we built, which is hard coded and not production ready. But it gives a good idea of the direction we are heading with the integration. I'd love to get feedback on this direction if you have some time. Any thoughts on how we could do things better, and if our assumptions are good or bad, would be great.

$(function(){

  // Breeze assumes asp.net mvc4 w/ WebAPI as the default
  // data services. To not use that, we have to create a
  // DataService instance and tell it where our end-point is,
  // and also tell it not to use any metadata
  var dataService = new breeze.DataService({
      serviceName: '/api/todos.php',
      hasServerMetadata: false
  });

  var manager = new breeze.EntityManager({
    dataService: dataService
  });

  // ---------------------------------------------

  var transport = {

    read: function(options){
      console.log("reading", options);

      var query = new breeze.EntityQuery("todos")
        .skip(options.data.skip)
        .take(options.data.take);

      manager.executeQuery(query).then(function(xhr){
        options.success(xhr.results);
      });
    }

  };

  var ds = new kendo.data.DataSource({
    transport: transport,
    autoSync: true,
    pageSize: 1,
    serverPaging: true,
    serverSorting: true,
    serverFiltering: true
  });

  $("#grid").kendoGrid({
    columns: [ 
      { field: "id" },
      { field: "description" }
    ],
    dataSource: ds,
    pageable: true,
    sortable: true,
    filterable: true
  });

});

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.