Backbone.js and RESTful web services
One of the more interesting things about Backbone.js is its integration with RESTful web services.
Let’s say I have the following web services:
URL | Verb | Description |
---|---|---|
/entities | GET | fetch entities |
/entities | POST | create entity |
/entities/id | PUT | modify entity |
/entities/id | DELETE | delete entity |
And that each service takes JSON objects or arrays of objects, where each object has the following properties (with sample values):
{ id: 1 // not needed for POST name: 'my name' }
You can see that this is exactly what Backbone.js expects.
I knocked the service up in Django, then wrote the following front-end app to demonstrate it. Notice the use of jQuery templates.
<!DOCTYPE html> <html lang="en"> <head> <title>Backbone.js REST Support Demo</title> </head> <body> <p><input id="new-name" type="text"><button id="add">Add</button></p> <div id="entities"></div> </body> <script id="entity-template" type="x-jquery-tmpl"> <input type="text" value="${name}"> <button>Delete</button> </script> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script> <script src="{{ STATIC_URL }}underscore-min.js"></script> <script src="{{ STATIC_URL }}backbone-min.js"></script> <script src="{{ STATIC_URL }}rest.js"></script> </html>
/*global Backbone, $, _ */ var Entities = {}; Entities.Collection = Backbone.Collection.extend({ url: '/entities' }); Entities.Views = {}; Entities.Views.Edit = Backbone.View.extend({ change: function () { this.model.set({ name: $(this.el).children('input').val() }); this.model.save(); }, destroy: function () { var el = this.el; this.model.destroy({ success: function () { $(el).remove(); } }); }, events: { 'click button': 'destroy', 'change input': 'change' }, initialize: function () { _(this).bindAll('change', 'destroy', 'render'); }, render: function () { $('#entity-template').tmpl(this.model.toJSON()).appendTo(this.el); this.delegateEvents(); } }); Entities.Views.List = Backbone.View.extend({ append: function (model) { var p = $('<p>').appendTo('#entities'), view = new Entities.Views.Edit({ model: model, el: p[0] }); view.render(); }, initialize: function () { _(this).bindAll('append', 'render'); this.collection.bind('refresh', this.render); this.collection.bind('add', this.append); }, render: function () { $('#entities').empty(); this.collection.each(function (model) { this.append(model); }, this); } }); $(function () { var collection = new Entities.Collection(), view = new Entities.Views.List({ collection: collection }); collection.fetch(); $('#add').click(function () { var model = new Backbone.Model({ name: $('#new-name').val() }); collection.add(model); model.save(); }); });