Backbone.Sails is a plugin that aims to leverage to best of a Sails backend within a Backbone frontend.
Sails is a nodejs framework built on top of express. It features fantastic support for web sockets, straight out of the box. As well as the extremely useful CRUD blueprint routes, which make GET'in, POST'in & DELETE'in a breeze. What's more, Sails supports these http 'verbs' through the client side web socket SDK sails.io.js. Allowing web developers to quickly build real-time applications that leverage the resourceful pub/sub events.
Backbone is an extremely popular and incredibly light weight javascript library that
gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling
In a nut shell, Backbone gives structure to client side javascript for single page applications. However, Backbone was never built with sockets in mind. Those familiar will know the default sync
method delegates to $.ajax
which itself delegates to XMLHttpRequest. Furthermore, Backbone Model's and Collection's only fire purely clientside events - making it fiddly to respond to server side events on the client.
This plugin attempts to bridge the gap between a Backbone frontend and a Sails backend. It has it's own Model and Collection class which support syncing over sockets (delegating to sails.io.js internally). Whats more, if the web socket isn't available, there are options to delegate to the original sync
function.
Perhaps more importantly, this plugin triggers the resourceful pub/sub events on client side Model and Collection instances. This allows you to respond to server side changes on your models and collections, within the 'Backbone ecosystem'. This ultimately reduces development time, increases maintainability and can serve as a pillar of programming architecture for larger socket based applications.
Sails blueprints also features great support for associations, population and filter/sort criteria. Backbone.Sails has built in functionality that helps streamline these powerful server side features into your Backbone workflow.
var Address;
var Person = Backbone.Sails.Model.extend({
modelName: "person",
assoc: {
address: function(){ return Address } // function returning address since circular dependence
},
config: {
populate: "address" // populate address by default (on fetch, save, etc)
}
})
var PersonCollection = Backbone.Sails.Collection.extend({ model: Person })
Address = Backbone.Sails.Model.extend({
modelName: "address"
assoc: {
occupants: PersonCollection
}
config: {
populate: "occupants"
}
})
var fred = new Person({ name: "fred", address: { street: "maple grove" } });
fred.save(); // will create address and a person, address will be populated
addressRaw = fred.get("address"); // this will grab the raw data for address (a POJO)
address = fred.get("address", true); // passing true will wrap the data with an Address constructor
address.set("number", 4).save();
// fetch is overloaded to call the 'populate' action, resolving with the address as a model
fred.fetch("address").done(function(address){
var jack = new Person({ name: "jack" })
address.addTo('occupants', jack) // will call the 'addTo' action, updating both the address and jack
.done(function(){
jack.isNew(); // false
address.get("occupants", true).findWhere({ name:"jack" }); // truthy (since occupants populated)
})
})
// you can specify filter criteria like this
var persons = new PersonCollection();
persons.query({
skip: 1,
limit: 1,
sort: "name ASC", // an object also works, e.g. { name: 1, street: -1 }
where: { name: { contains: "a" } }
}).fetch()
// unlike sails, populate can take filter criteria as well
address.populate({
occupants: {
limit: 2,
where: {
name: "fred"
}
}
}).fetch()
A 0.1 release is currently available. Sails v0.10 is required as well as io.sails v0.9.
Backbone.Sails depends on
npm install sails@^0.10
The server side blueprints depend on lodash and bluebird, so you'll need to run
npm install bluebird --save
npm install lodash --save
On The Client
Include backbone.sails.js
after it's dependencies have been included. Backbone.Sails
should be available thereafter.
On The Server
Copy/paste the blueprints folder to api/blueprints
. The blueprints are backwards compatible with the original sails blueprints.
Whilst you are familiarizing yourself with the API, I suggest setting the following blueprint options within config/blueprints.js
:
mirror: true
mirror
return's socket event's back to the client they originated from - utterly crucial for testing/learning and DRY'ing up your front end.
autowatch: true
autowatch
is a flag to the find
blueprint indicating to subscribe the client to created
events. A good default is true, whilst your learning. (There is also a configuration option to dynamically flag this on or off from the client with Backbone.Sails)
The documentation currently available is:
Backbone.Sails.Model
referenceBackbone.Sails.Collection
referenceBackbone.Sails
referenceThere is also an example chat client application that can be found here that was developed with Backbone.Marionette in coffeescript.
You can also get a good idea of what Backbone.Sails is capable of by looking at the test code.
Thanks for your interest! Please see my GitHub or Linkedin to stay updated.
The MIT License (MIT)
Copyright (c) 2022 Ian Haggerty
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.